Home | History | Annotate | Download | only in socket
      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_mac.h"
      6 
      7 #include <CoreServices/CoreServices.h>
      8 #include <netdb.h>
      9 #include <sys/socket.h>
     10 #include <sys/types.h>
     11 
     12 #include <algorithm>
     13 
     14 #include "base/lazy_instance.h"
     15 #include "base/mac/scoped_cftyperef.h"
     16 #include "base/string_util.h"
     17 #include "net/base/address_list.h"
     18 #include "net/base/cert_verifier.h"
     19 #include "net/base/io_buffer.h"
     20 #include "net/base/net_errors.h"
     21 #include "net/base/net_log.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 #include "net/socket/ssl_error_params.h"
     27 
     28 // Welcome to Mac SSL. We've been waiting for you.
     29 //
     30 // The Mac SSL implementation is, like the Windows and NSS implementations, a
     31 // giant state machine. This design constraint is due to the asynchronous nature
     32 // of our underlying transport mechanism. We can call down to read/write on the
     33 // network, but what happens is that either it completes immediately or returns
     34 // saying that we'll get a callback sometime in the future. In that case, we
     35 // have to return to our caller but pick up where we left off when we
     36 // resume. Thus the fun.
     37 //
     38 // On Windows, we use Security Contexts, which are driven by us. We fetch data
     39 // from the network, we call the context to decrypt the data, and so on. On the
     40 // Mac, however, we provide Secure Transport with callbacks to get data from the
     41 // network, and it calls us back to fetch the data from the network for
     42 // it. Therefore, there are different sets of states in our respective state
     43 // machines, fewer on the Mac because Secure Transport keeps a lot of its own
     44 // state. The discussion about what each of the states means lives in comments
     45 // in the DoHandshakeLoop() function.
     46 //
     47 // Secure Transport is designed for use by either blocking or non-blocking
     48 // network I/O. If, for example, you called SSLRead() to fetch data, Secure
     49 // Transport will, unless it has some cached data, issue a read to your network
     50 // callback read function to fetch it some more encrypted data. It's expecting
     51 // one of two things. If your function is hooked up to a blocking source, then
     52 // it'll block pending receipt of the data from the other end. That's fine, as
     53 // when you return with the data, Secure Transport will do its thing. On the
     54 // other hand, suppose that your socket is non-blocking and tells your function
     55 // that it would block. Then you let Secure Transport know, and it'll tell the
     56 // original caller that it would have blocked and that they need to call it
     57 // "later."
     58 //
     59 // When's "later," though? We have fully-asynchronous networking, so we get a
     60 // callback when our data's ready. But Secure Transport has no way for us to
     61 // tell it that data has arrived, so we must re-execute the call that triggered
     62 // the I/O (we rely on our state machine to do this). When we do so Secure
     63 // Transport will ask once again for the data. Chances are that it'll be the
     64 // same request as the previous time, but that's not actually guaranteed. But as
     65 // long as we buffer what we have and keep track of where we were, it works
     66 // quite well.
     67 //
     68 // Except for network writes. They shoot this plan straight to hell.
     69 //
     70 // Faking a blocking connection with an asynchronous connection (theoretically
     71 // more powerful) simply doesn't work for writing. Suppose that Secure Transport
     72 // requests a write of data to the network. With blocking I/O, we'd just block
     73 // until the write completed, and with non-blocking I/O we'd know how many bytes
     74 // we wrote before we would have blocked. But with the asynchronous I/O, the
     75 // transport underneath us can tell us that it'll let us know sometime "later"
     76 // whether or not things succeeded, and how many bytes were written. What do we
     77 // return to Secure Transport? We can't return a byte count, but we can't return
     78 // "later" as we're not guaranteed to be called in the future with the same data
     79 // to write.
     80 //
     81 // So, like in any good relationship, we're forced to lie. Whenever Secure
     82 // Transport asks for data to be written, we take it all and lie about it always
     83 // being written. We spin in a loop (see SSLWriteCallback() and
     84 // OnTransportWriteComplete()) independent of the main state machine writing
     85 // the data to the network, and get the data out. The main consequence of this
     86 // independence from the state machine is that we require a full-duplex
     87 // transport underneath us since we can't use it to keep our reading and
     88 // writing straight. Fortunately, the NSS implementation also has this issue
     89 // to deal with, so we share the same Libevent-based full-duplex TCP socket.
     90 //
     91 // A side comment on return values might be in order. Those who haven't taken
     92 // the time to read the documentation (ahem, header comments) in our various
     93 // files might be a bit surprised to see result values being treated as both
     94 // lengths and errors. Like Shimmer, they are both. In both the case of
     95 // immediate results as well as results returned in callbacks, a negative return
     96 // value indicates an error, a zero return value indicates end-of-stream (for
     97 // reads), and a positive return value indicates the number of bytes read or
     98 // written. Thus, many functions start off with |if (result < 0) return
     99 // result;|. That gets the error condition out of the way, and from that point
    100 // forward the result can be treated as a length.
    101 
    102 namespace net {
    103 
    104 namespace {
    105 
    106 // Pause if we have 2MB of data in flight, resume once we're down below 1MB.
    107 const unsigned int kWriteSizePauseLimit = 2 * 1024 * 1024;
    108 const unsigned int kWriteSizeResumeLimit = 1 * 1024 * 1024;
    109 
    110 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
    111 // When compiled against the Mac OS X 10.5 SDK, define symbolic constants for
    112 // cipher suites added in Mac OS X 10.6.
    113 enum {
    114   // ECC cipher suites from RFC 4492.
    115   TLS_ECDH_ECDSA_WITH_NULL_SHA           = 0xC001,
    116   TLS_ECDH_ECDSA_WITH_RC4_128_SHA        = 0xC002,
    117   TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA   = 0xC003,
    118   TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA    = 0xC004,
    119   TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA    = 0xC005,
    120   TLS_ECDHE_ECDSA_WITH_NULL_SHA          = 0xC006,
    121   TLS_ECDHE_ECDSA_WITH_RC4_128_SHA       = 0xC007,
    122   TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA  = 0xC008,
    123   TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA   = 0xC009,
    124   TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA   = 0xC00A,
    125   TLS_ECDH_RSA_WITH_NULL_SHA             = 0xC00B,
    126   TLS_ECDH_RSA_WITH_RC4_128_SHA          = 0xC00C,
    127   TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA     = 0xC00D,
    128   TLS_ECDH_RSA_WITH_AES_128_CBC_SHA      = 0xC00E,
    129   TLS_ECDH_RSA_WITH_AES_256_CBC_SHA      = 0xC00F,
    130   TLS_ECDHE_RSA_WITH_NULL_SHA            = 0xC010,
    131   TLS_ECDHE_RSA_WITH_RC4_128_SHA         = 0xC011,
    132   TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA    = 0xC012,
    133   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA     = 0xC013,
    134   TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA     = 0xC014,
    135   TLS_ECDH_anon_WITH_NULL_SHA            = 0xC015,
    136   TLS_ECDH_anon_WITH_RC4_128_SHA         = 0xC016,
    137   TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA    = 0xC017,
    138   TLS_ECDH_anon_WITH_AES_128_CBC_SHA     = 0xC018,
    139   TLS_ECDH_anon_WITH_AES_256_CBC_SHA     = 0xC019,
    140 };
    141 #endif
    142 
    143 // For an explanation of the Mac OS X error codes, please refer to:
    144 // http://developer.apple.com/mac/library/documentation/Security/Reference/secureTransportRef/Reference/reference.html
    145 int NetErrorFromOSStatus(OSStatus status) {
    146   switch (status) {
    147     case errSSLWouldBlock:
    148       return ERR_IO_PENDING;
    149     case paramErr:
    150     case errSSLBadCipherSuite:
    151     case errSSLBadConfiguration:
    152       return ERR_INVALID_ARGUMENT;
    153     case errSSLClosedNoNotify:
    154       return ERR_CONNECTION_RESET;
    155     case errSSLClosedAbort:
    156       return ERR_CONNECTION_ABORTED;
    157     case errSSLInternal:
    158       return ERR_UNEXPECTED;
    159     case errSSLBadRecordMac:
    160     case errSSLCrypto:
    161     case errSSLConnectionRefused:
    162     case errSSLDecryptionFail:
    163     case errSSLFatalAlert:
    164     case errSSLIllegalParam:  // Received an illegal_parameter alert.
    165     case errSSLPeerDecodeError:  // Received a decode_error alert.
    166     case errSSLPeerDecryptError:  // Received a decrypt_error alert.
    167     case errSSLPeerExportRestriction:  // Received an export_restriction alert.
    168     case errSSLPeerHandshakeFail:  // Received a handshake_failure alert.
    169     case errSSLPeerNoRenegotiation:  // Received a no_renegotiation alert
    170     case errSSLPeerUnexpectedMsg:  // Received an unexpected_message alert.
    171     case errSSLProtocol:
    172     case errSSLRecordOverflow:
    173       return ERR_SSL_PROTOCOL_ERROR;
    174     case errSSLHostNameMismatch:
    175       return ERR_CERT_COMMON_NAME_INVALID;
    176     case errSSLCertExpired:
    177     case errSSLCertNotYetValid:
    178       return ERR_CERT_DATE_INVALID;
    179     case errSSLNoRootCert:
    180     case errSSLUnknownRootCert:
    181       return ERR_CERT_AUTHORITY_INVALID;
    182     case errSSLXCertChainInvalid:
    183     case errSSLBadCert:
    184       return ERR_CERT_INVALID;
    185 
    186     case errSSLClosedGraceful:
    187     case noErr:
    188       return OK;
    189 
    190     // (Note that all errSSLPeer* codes indicate errors reported by the peer,
    191     // so the cert-related ones refer to my _client_ cert.)
    192     // TODO(wtc): Add fine-grained error codes for client certificate errors
    193     // reported by the server using the following SSL/TLS alert messages:
    194     //   access_denied
    195     //   bad_certificate
    196     //   unsupported_certificate
    197     //   certificate_expired
    198     //   certificate_revoked
    199     //   certificate_unknown
    200     //   unknown_ca
    201     case errSSLPeerCertUnknown...errSSLPeerBadCert:
    202     case errSSLPeerUnknownCA:
    203     case errSSLPeerAccessDenied:
    204       LOG(WARNING) << "Server rejected client cert (OSStatus=" << status << ")";
    205       return ERR_BAD_SSL_CLIENT_AUTH_CERT;
    206 
    207     case errSSLNegotiation:
    208     case errSSLPeerInsufficientSecurity:
    209     case errSSLPeerProtocolVersion:
    210       return ERR_SSL_VERSION_OR_CIPHER_MISMATCH;
    211 
    212     case errSSLBufferOverflow:
    213     case errSSLModuleAttach:
    214     case errSSLSessionNotFound:
    215     default:
    216       LOG(WARNING) << "Unknown error " << status <<
    217           " mapped to net::ERR_FAILED";
    218       return ERR_FAILED;
    219   }
    220 }
    221 
    222 OSStatus OSStatusFromNetError(int net_error) {
    223   switch (net_error) {
    224     case ERR_IO_PENDING:
    225       return errSSLWouldBlock;
    226     case ERR_INTERNET_DISCONNECTED:
    227     case ERR_TIMED_OUT:
    228     case ERR_CONNECTION_ABORTED:
    229     case ERR_CONNECTION_RESET:
    230     case ERR_CONNECTION_REFUSED:
    231     case ERR_ADDRESS_UNREACHABLE:
    232     case ERR_ADDRESS_INVALID:
    233       return errSSLClosedAbort;
    234     case ERR_UNEXPECTED:
    235       return errSSLInternal;
    236     case ERR_INVALID_ARGUMENT:
    237       return paramErr;
    238     case OK:
    239       return noErr;
    240     default:
    241       LOG(WARNING) << "Unknown error " << net_error <<
    242           " mapped to paramErr";
    243       return paramErr;
    244   }
    245 }
    246 
    247 // Converts from a cipher suite to its key size. If the suite is marked with a
    248 // **, it's not actually implemented in Secure Transport and won't be returned
    249 // (but we'll code for it anyway).  The reference here is
    250 // http://www.opensource.apple.com/darwinsource/10.5.5/libsecurity_ssl-32463/lib/cipherSpecs.c
    251 // Seriously, though, there has to be an API for this, but I can't find one.
    252 // Anybody?
    253 int KeySizeOfCipherSuite(SSLCipherSuite suite) {
    254   switch (suite) {
    255     // SSL 2 only
    256 
    257     case SSL_RSA_WITH_DES_CBC_MD5:
    258       return 56;
    259     case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
    260       return 112;
    261     case SSL_RSA_WITH_RC2_CBC_MD5:
    262     case SSL_RSA_WITH_IDEA_CBC_MD5:              // **
    263       return 128;
    264     case SSL_NO_SUCH_CIPHERSUITE:                // **
    265       return 0;
    266 
    267     // SSL 2, 3, TLS
    268 
    269     case SSL_NULL_WITH_NULL_NULL:
    270     case SSL_RSA_WITH_NULL_MD5:
    271     case SSL_RSA_WITH_NULL_SHA:                  // **
    272     case SSL_FORTEZZA_DMS_WITH_NULL_SHA:         // **
    273     case TLS_ECDH_ECDSA_WITH_NULL_SHA:
    274     case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
    275     case TLS_ECDH_RSA_WITH_NULL_SHA:
    276     case TLS_ECDHE_RSA_WITH_NULL_SHA:
    277     case TLS_ECDH_anon_WITH_NULL_SHA:
    278       return 0;
    279     case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
    280     case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
    281     case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
    282     case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:   // **
    283     case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:   // **
    284     case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
    285     case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
    286     case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
    287     case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
    288       return 40;
    289     case SSL_RSA_WITH_DES_CBC_SHA:
    290     case SSL_DH_DSS_WITH_DES_CBC_SHA:            // **
    291     case SSL_DH_RSA_WITH_DES_CBC_SHA:            // **
    292     case SSL_DHE_DSS_WITH_DES_CBC_SHA:
    293     case SSL_DHE_RSA_WITH_DES_CBC_SHA:
    294     case SSL_DH_anon_WITH_DES_CBC_SHA:
    295       return 56;
    296     case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: // **
    297       return 80;
    298     case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
    299     case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:       // **
    300     case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:       // **
    301     case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
    302     case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
    303     case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
    304     case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
    305     case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
    306     case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
    307     case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
    308     case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
    309       return 112;
    310     case SSL_RSA_WITH_RC4_128_MD5:
    311     case SSL_RSA_WITH_RC4_128_SHA:
    312     case SSL_RSA_WITH_IDEA_CBC_SHA:              // **
    313     case SSL_DH_anon_WITH_RC4_128_MD5:
    314     case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
    315     case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
    316     case TLS_ECDH_RSA_WITH_RC4_128_SHA:
    317     case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
    318     case TLS_ECDH_anon_WITH_RC4_128_SHA:
    319       return 128;
    320 
    321     // TLS AES options (see RFC 3268 and RFC 4492)
    322 
    323     case TLS_RSA_WITH_AES_128_CBC_SHA:
    324     case TLS_DH_DSS_WITH_AES_128_CBC_SHA:        // **
    325     case TLS_DH_RSA_WITH_AES_128_CBC_SHA:        // **
    326     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
    327     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
    328     case TLS_DH_anon_WITH_AES_128_CBC_SHA:
    329     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
    330     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
    331     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
    332     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
    333     case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
    334       return 128;
    335     case TLS_RSA_WITH_AES_256_CBC_SHA:
    336     case TLS_DH_DSS_WITH_AES_256_CBC_SHA:        // **
    337     case TLS_DH_RSA_WITH_AES_256_CBC_SHA:        // **
    338     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
    339     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
    340     case TLS_DH_anon_WITH_AES_256_CBC_SHA:
    341     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
    342     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
    343     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
    344     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
    345     case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
    346       return 256;
    347 
    348     default:
    349       return -1;
    350   }
    351 }
    352 
    353 // Whitelist the cipher suites we want to enable.  We disable the following
    354 // cipher suites.
    355 // - Null encryption cipher suites.
    356 // - Weak cipher suites: < 80 bits of security strength.
    357 // - FORTEZZA cipher suites (obsolete).
    358 // - IDEA cipher suites (RFC 5469 explains why).
    359 // - Anonymous cipher suites.
    360 //
    361 // Why don't we use a blacklist?  A blacklist that isn't updated for a new
    362 // Mac OS X release is a potential security issue because the new release
    363 // may have new null encryption or anonymous cipher suites, whereas a
    364 // whitelist that isn't updated for a new Mac OS X release just means we
    365 // won't support any new cipher suites in that release.
    366 bool ShouldEnableCipherSuite(SSLCipherSuite suite) {
    367   switch (suite) {
    368     case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
    369     case SSL_RSA_WITH_RC2_CBC_MD5:
    370 
    371     case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
    372     case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:       // **
    373     case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:       // **
    374     case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
    375     case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
    376     case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
    377     case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
    378     case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
    379     case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
    380 
    381     case SSL_RSA_WITH_RC4_128_MD5:
    382     case SSL_RSA_WITH_RC4_128_SHA:
    383     case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
    384     case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
    385     case TLS_ECDH_RSA_WITH_RC4_128_SHA:
    386     case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
    387 
    388     case TLS_RSA_WITH_AES_128_CBC_SHA:
    389     case TLS_DH_DSS_WITH_AES_128_CBC_SHA:        // **
    390     case TLS_DH_RSA_WITH_AES_128_CBC_SHA:        // **
    391     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
    392     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
    393     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
    394     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
    395     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
    396     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
    397 
    398     case TLS_RSA_WITH_AES_256_CBC_SHA:
    399     case TLS_DH_DSS_WITH_AES_256_CBC_SHA:        // **
    400     case TLS_DH_RSA_WITH_AES_256_CBC_SHA:        // **
    401     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
    402     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
    403     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
    404     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
    405     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
    406     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
    407       return true;
    408 
    409     default:
    410       return false;
    411   }
    412 }
    413 
    414 // Returns the server's certificate.  The caller must release a reference
    415 // to the return value when done.  Returns NULL on failure.
    416 X509Certificate* GetServerCert(SSLContextRef ssl_context) {
    417   CFArrayRef certs;
    418   OSStatus status = SSLCopyPeerCertificates(ssl_context, &certs);
    419   // SSLCopyPeerCertificates may succeed but return a null |certs|
    420   // (if we're using an anonymous cipher suite or if we call it
    421   // before the certificate message has arrived and been parsed).
    422   if (status != noErr || !certs)
    423     return NULL;
    424   base::mac::ScopedCFTypeRef<CFArrayRef> scoped_certs(certs);
    425 
    426   DCHECK_GT(CFArrayGetCount(certs), 0);
    427 
    428   // Add each of the intermediate certificates in the server's chain to the
    429   // server's X509Certificate object. This makes them available to
    430   // X509Certificate::Verify() for chain building.
    431   std::vector<SecCertificateRef> intermediate_ca_certs;
    432   CFIndex certs_length = CFArrayGetCount(certs);
    433   for (CFIndex i = 1; i < certs_length; ++i) {
    434     SecCertificateRef cert_ref = reinterpret_cast<SecCertificateRef>(
    435         const_cast<void*>(CFArrayGetValueAtIndex(certs, i)));
    436     intermediate_ca_certs.push_back(cert_ref);
    437   }
    438 
    439   SecCertificateRef server_cert = static_cast<SecCertificateRef>(
    440       const_cast<void*>(CFArrayGetValueAtIndex(certs, 0)));
    441   return X509Certificate::CreateFromHandle(
    442       server_cert, X509Certificate::SOURCE_FROM_NETWORK, intermediate_ca_certs);
    443 }
    444 
    445 // Dynamically look up a pointer to a function exported by a bundle.
    446 template <typename FNTYPE>
    447 FNTYPE LookupFunction(CFStringRef bundleName, CFStringRef fnName) {
    448   CFBundleRef bundle = CFBundleGetBundleWithIdentifier(bundleName);
    449   if (!bundle)
    450     return NULL;
    451   return reinterpret_cast<FNTYPE>(
    452       CFBundleGetFunctionPointerForName(bundle, fnName));
    453 }
    454 
    455 struct CipherSuiteIsDisabledFunctor {
    456   explicit CipherSuiteIsDisabledFunctor(
    457       const std::vector<uint16>& disabled_cipher_suites)
    458       : disabled_cipher_suites_(disabled_cipher_suites) {}
    459 
    460   // Returns true if the given |cipher_suite| appears within the set of
    461   // |disabled_cipher_suites|.
    462   bool operator()(SSLCipherSuite cipher_suite) const {
    463     return binary_search(disabled_cipher_suites_.begin(),
    464                          disabled_cipher_suites_.end(),
    465                          static_cast<uint16>(cipher_suite));
    466   }
    467 
    468   const std::vector<uint16>& disabled_cipher_suites_;
    469 };
    470 
    471 // Class to determine what cipher suites are available and which cipher
    472 // suites should be enabled, based on the overall security policy.
    473 class EnabledCipherSuites {
    474  public:
    475   const std::vector<SSLCipherSuite>& ciphers() const { return ciphers_; }
    476 
    477  private:
    478   friend struct base::DefaultLazyInstanceTraits<EnabledCipherSuites>;
    479   EnabledCipherSuites();
    480   ~EnabledCipherSuites() {}
    481 
    482   std::vector<SSLCipherSuite> ciphers_;
    483 
    484   DISALLOW_COPY_AND_ASSIGN(EnabledCipherSuites);
    485 };
    486 
    487 static base::LazyInstance<EnabledCipherSuites> g_enabled_cipher_suites(
    488     base::LINKER_INITIALIZED);
    489 
    490 EnabledCipherSuites::EnabledCipherSuites() {
    491   SSLContextRef ssl_context;
    492   OSStatus status = SSLNewContext(false, &ssl_context);
    493   if (status != noErr)
    494     return;
    495 
    496   size_t num_supported_ciphers;
    497   status = SSLGetNumberSupportedCiphers(ssl_context, &num_supported_ciphers);
    498   if (status != noErr) {
    499     SSLDisposeContext(ssl_context);
    500     return;
    501   }
    502   DCHECK_NE(num_supported_ciphers, 0U);
    503 
    504   std::vector<SSLCipherSuite> supported_ciphers(num_supported_ciphers);
    505   status = SSLGetSupportedCiphers(ssl_context, &supported_ciphers[0],
    506                                   &num_supported_ciphers);
    507   SSLDisposeContext(ssl_context);
    508   if (status != noErr)
    509     return;
    510 
    511   for (size_t i = 0; i < num_supported_ciphers; ++i) {
    512     if (ShouldEnableCipherSuite(supported_ciphers[i]))
    513       ciphers_.push_back(supported_ciphers[i]);
    514   }
    515 }
    516 
    517 }  // namespace
    518 
    519 //-----------------------------------------------------------------------------
    520 
    521 SSLClientSocketMac::SSLClientSocketMac(ClientSocketHandle* transport_socket,
    522                                        const HostPortPair& host_and_port,
    523                                        const SSLConfig& ssl_config,
    524                                        CertVerifier* cert_verifier)
    525     : handshake_io_callback_(this, &SSLClientSocketMac::OnHandshakeIOComplete),
    526       transport_read_callback_(this,
    527                                &SSLClientSocketMac::OnTransportReadComplete),
    528       transport_write_callback_(this,
    529                                 &SSLClientSocketMac::OnTransportWriteComplete),
    530       transport_(transport_socket),
    531       host_and_port_(host_and_port),
    532       ssl_config_(ssl_config),
    533       user_connect_callback_(NULL),
    534       user_read_callback_(NULL),
    535       user_write_callback_(NULL),
    536       user_read_buf_len_(0),
    537       user_write_buf_len_(0),
    538       next_handshake_state_(STATE_NONE),
    539       cert_verifier_(cert_verifier),
    540       renegotiating_(false),
    541       client_cert_requested_(false),
    542       ssl_context_(NULL),
    543       bytes_read_after_renegotiation_(0),
    544       pending_send_error_(OK),
    545       net_log_(transport_socket->socket()->NetLog()) {
    546   // Sort the list of ciphers to disable, since disabling ciphers on Mac
    547   // requires subtracting from a list of enabled ciphers while maintaining
    548   // ordering, as opposed to merely needing to iterate them as with NSS.
    549   sort(ssl_config_.disabled_cipher_suites.begin(),
    550        ssl_config_.disabled_cipher_suites.end());
    551 }
    552 
    553 SSLClientSocketMac::~SSLClientSocketMac() {
    554   Disconnect();
    555 }
    556 
    557 #ifdef ANDROID
    558 // TODO(kristianm): handle the case when wait_for_connect is true
    559 // (sync requests)
    560 #endif
    561 int SSLClientSocketMac::Connect(CompletionCallback* callback
    562 #ifdef ANDROID
    563                                 , bool wait_for_connect
    564 #endif
    565                                ) {
    566   DCHECK(transport_.get());
    567   DCHECK(next_handshake_state_ == STATE_NONE);
    568   DCHECK(!user_connect_callback_);
    569 
    570   net_log_.BeginEvent(NetLog::TYPE_SSL_CONNECT, NULL);
    571 
    572   int rv = InitializeSSLContext();
    573   if (rv != OK) {
    574     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
    575     return rv;
    576   }
    577 
    578   next_handshake_state_ = STATE_HANDSHAKE;
    579   rv = DoHandshakeLoop(OK);
    580   if (rv == ERR_IO_PENDING) {
    581     user_connect_callback_ = callback;
    582   } else {
    583     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
    584   }
    585   return rv;
    586 }
    587 
    588 void SSLClientSocketMac::Disconnect() {
    589   next_handshake_state_ = STATE_NONE;
    590 
    591   if (ssl_context_) {
    592     SSLClose(ssl_context_);
    593     SSLDisposeContext(ssl_context_);
    594     ssl_context_ = NULL;
    595     VLOG(1) << "----- Disposed SSLContext";
    596   }
    597 
    598   // Shut down anything that may call us back.
    599   verifier_.reset();
    600   transport_->socket()->Disconnect();
    601 }
    602 
    603 bool SSLClientSocketMac::IsConnected() const {
    604   // Ideally, we should also check if we have received the close_notify alert
    605   // message from the server, and return false in that case.  We're not doing
    606   // that, so this function may return a false positive.  Since the upper
    607   // layer (HttpNetworkTransaction) needs to handle a persistent connection
    608   // closed by the server when we send a request anyway, a false positive in
    609   // exchange for simpler code is a good trade-off.
    610   return completed_handshake() && transport_->socket()->IsConnected();
    611 }
    612 
    613 bool SSLClientSocketMac::IsConnectedAndIdle() const {
    614   // Unlike IsConnected, this method doesn't return a false positive.
    615   //
    616   // Strictly speaking, we should check if we have received the close_notify
    617   // alert message from the server, and return false in that case.  Although
    618   // the close_notify alert message means EOF in the SSL layer, it is just
    619   // bytes to the transport layer below, so
    620   // transport_->socket()->IsConnectedAndIdle() returns the desired false
    621   // when we receive close_notify.
    622   return completed_handshake() && transport_->socket()->IsConnectedAndIdle();
    623 }
    624 
    625 int SSLClientSocketMac::GetPeerAddress(AddressList* address) const {
    626   return transport_->socket()->GetPeerAddress(address);
    627 }
    628 
    629 int SSLClientSocketMac::GetLocalAddress(IPEndPoint* address) const {
    630   return transport_->socket()->GetLocalAddress(address);
    631 }
    632 
    633 const BoundNetLog& SSLClientSocketMac::NetLog() const {
    634   return net_log_;
    635 }
    636 
    637 void SSLClientSocketMac::SetSubresourceSpeculation() {
    638   if (transport_.get() && transport_->socket()) {
    639     transport_->socket()->SetSubresourceSpeculation();
    640   } else {
    641     NOTREACHED();
    642   }
    643 }
    644 
    645 void SSLClientSocketMac::SetOmniboxSpeculation() {
    646   if (transport_.get() && transport_->socket()) {
    647     transport_->socket()->SetOmniboxSpeculation();
    648   } else {
    649     NOTREACHED();
    650   }
    651 }
    652 
    653 bool SSLClientSocketMac::WasEverUsed() const {
    654   if (transport_.get() && transport_->socket()) {
    655     return transport_->socket()->WasEverUsed();
    656   }
    657   NOTREACHED();
    658   return false;
    659 }
    660 
    661 bool SSLClientSocketMac::UsingTCPFastOpen() const {
    662   if (transport_.get() && transport_->socket()) {
    663     return transport_->socket()->UsingTCPFastOpen();
    664   }
    665   NOTREACHED();
    666   return false;
    667 }
    668 
    669 int SSLClientSocketMac::Read(IOBuffer* buf, int buf_len,
    670                              CompletionCallback* callback) {
    671   DCHECK(completed_handshake());
    672   DCHECK(!user_read_callback_);
    673   DCHECK(!user_read_buf_);
    674 
    675   user_read_buf_ = buf;
    676   user_read_buf_len_ = buf_len;
    677 
    678   int rv = DoPayloadRead();
    679   if (rv == ERR_IO_PENDING) {
    680     user_read_callback_ = callback;
    681   } else {
    682     user_read_buf_ = NULL;
    683     user_read_buf_len_ = 0;
    684   }
    685   return rv;
    686 }
    687 
    688 int SSLClientSocketMac::Write(IOBuffer* buf, int buf_len,
    689                               CompletionCallback* callback) {
    690   DCHECK(completed_handshake());
    691   DCHECK(!user_write_callback_);
    692   DCHECK(!user_write_buf_);
    693 
    694   user_write_buf_ = buf;
    695   user_write_buf_len_ = buf_len;
    696 
    697   int rv = DoPayloadWrite();
    698   if (rv == ERR_IO_PENDING) {
    699     user_write_callback_ = callback;
    700   } else {
    701     user_write_buf_ = NULL;
    702     user_write_buf_len_ = 0;
    703   }
    704   return rv;
    705 }
    706 
    707 bool SSLClientSocketMac::SetReceiveBufferSize(int32 size) {
    708   return transport_->socket()->SetReceiveBufferSize(size);
    709 }
    710 
    711 bool SSLClientSocketMac::SetSendBufferSize(int32 size) {
    712   return transport_->socket()->SetSendBufferSize(size);
    713 }
    714 
    715 void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) {
    716   ssl_info->Reset();
    717   if (!server_cert_) {
    718     NOTREACHED();
    719     return;
    720   }
    721 
    722   ssl_info->cert = server_cert_;
    723   ssl_info->cert_status = server_cert_verify_result_.cert_status;
    724   ssl_info->public_key_hashes = server_cert_verify_result_.public_key_hashes;
    725   ssl_info->is_issued_by_known_root =
    726       server_cert_verify_result_.is_issued_by_known_root;
    727 
    728   // security info
    729   SSLCipherSuite suite;
    730   OSStatus status = SSLGetNegotiatedCipher(ssl_context_, &suite);
    731   if (!status) {
    732     ssl_info->security_bits = KeySizeOfCipherSuite(suite);
    733     ssl_info->connection_status |=
    734         (suite & SSL_CONNECTION_CIPHERSUITE_MASK) <<
    735         SSL_CONNECTION_CIPHERSUITE_SHIFT;
    736   }
    737 
    738   if (ssl_config_.ssl3_fallback)
    739     ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK;
    740 }
    741 
    742 void SSLClientSocketMac::GetSSLCertRequestInfo(
    743     SSLCertRequestInfo* cert_request_info) {
    744   // I'm being asked for available client certs (identities).
    745   // First, get the cert issuer names allowed by the server.
    746   std::vector<CertPrincipal> valid_issuers;
    747   CFArrayRef valid_issuer_names = NULL;
    748   if (SSLCopyDistinguishedNames(ssl_context_, &valid_issuer_names) == noErr &&
    749       valid_issuer_names != NULL) {
    750     VLOG(1) << "Server has " << CFArrayGetCount(valid_issuer_names)
    751             << " valid issuer names";
    752     int n = CFArrayGetCount(valid_issuer_names);
    753     for (int i = 0; i < n; i++) {
    754       // Parse each name into a CertPrincipal object.
    755       CFDataRef issuer = reinterpret_cast<CFDataRef>(
    756           CFArrayGetValueAtIndex(valid_issuer_names, i));
    757       CertPrincipal p;
    758       if (p.ParseDistinguishedName(CFDataGetBytePtr(issuer),
    759                                    CFDataGetLength(issuer))) {
    760         valid_issuers.push_back(p);
    761       }
    762     }
    763     CFRelease(valid_issuer_names);
    764   }
    765 
    766   // Now get the available client certs whose issuers are allowed by the server.
    767   cert_request_info->host_and_port = host_and_port_.ToString();
    768   cert_request_info->client_certs.clear();
    769   // TODO(rch):  we should consider passing a host-port pair as the first
    770   // argument to X509Certificate::GetSSLClientCertificates.
    771   X509Certificate::GetSSLClientCertificates(host_and_port_.host(),
    772                                             valid_issuers,
    773                                             &cert_request_info->client_certs);
    774   VLOG(1) << "Asking user to choose between "
    775           << cert_request_info->client_certs.size() << " client certs...";
    776 }
    777 
    778 SSLClientSocket::NextProtoStatus
    779 SSLClientSocketMac::GetNextProto(std::string* proto) {
    780   proto->clear();
    781   return kNextProtoUnsupported;
    782 }
    783 
    784 int SSLClientSocketMac::InitializeSSLContext() {
    785   VLOG(1) << "----- InitializeSSLContext";
    786   OSStatus status = noErr;
    787 
    788   status = SSLNewContext(false, &ssl_context_);
    789   if (status)
    790     return NetErrorFromOSStatus(status);
    791 
    792   status = SSLSetProtocolVersionEnabled(ssl_context_,
    793                                         kSSLProtocol2,
    794                                         false);
    795   if (status)
    796     return NetErrorFromOSStatus(status);
    797 
    798   status = SSLSetProtocolVersionEnabled(ssl_context_,
    799                                         kSSLProtocol3,
    800                                         ssl_config_.ssl3_enabled);
    801   if (status)
    802     return NetErrorFromOSStatus(status);
    803 
    804   status = SSLSetProtocolVersionEnabled(ssl_context_,
    805                                         kTLSProtocol1,
    806                                         ssl_config_.tls1_enabled);
    807   if (status)
    808     return NetErrorFromOSStatus(status);
    809 
    810   std::vector<SSLCipherSuite> enabled_ciphers =
    811       g_enabled_cipher_suites.Get().ciphers();
    812 
    813   CipherSuiteIsDisabledFunctor is_disabled_cipher(
    814       ssl_config_.disabled_cipher_suites);
    815   std::vector<SSLCipherSuite>::iterator new_end =
    816       std::remove_if(enabled_ciphers.begin(), enabled_ciphers.end(),
    817                      is_disabled_cipher);
    818   if (new_end != enabled_ciphers.end())
    819     enabled_ciphers.erase(new_end, enabled_ciphers.end());
    820 
    821   status = SSLSetEnabledCiphers(
    822       ssl_context_,
    823       enabled_ciphers.empty() ? NULL : &enabled_ciphers[0],
    824       enabled_ciphers.size());
    825 
    826   if (status)
    827     return NetErrorFromOSStatus(status);
    828 
    829   status = SSLSetIOFuncs(ssl_context_, SSLReadCallback, SSLWriteCallback);
    830   if (status)
    831     return NetErrorFromOSStatus(status);
    832 
    833   status = SSLSetConnection(ssl_context_, this);
    834   if (status)
    835     return NetErrorFromOSStatus(status);
    836 
    837   // Passing the domain name enables the server_name TLS extension (SNI).
    838   status = SSLSetPeerDomainName(ssl_context_,
    839                                 host_and_port_.host().data(),
    840                                 host_and_port_.host().length());
    841   if (status)
    842     return NetErrorFromOSStatus(status);
    843 
    844   // Disable certificate verification within Secure Transport; we'll
    845   // be handling that ourselves.
    846   status = SSLSetEnableCertVerify(ssl_context_, false);
    847   if (status)
    848     return NetErrorFromOSStatus(status);
    849 
    850   if (ssl_config_.send_client_cert) {
    851     status = SetClientCert();
    852     if (status)
    853       return NetErrorFromOSStatus(status);
    854     return OK;
    855   }
    856 
    857   // Concatenate the hostname and peer address to use as the peer ID. To
    858   // resume a session, we must connect to the same server on the same port
    859   // using the same hostname (i.e., localhost and 127.0.0.1 are considered
    860   // different peers, which puts us through certificate validation again
    861   // and catches hostname/certificate name mismatches.
    862   AddressList address;
    863   int rv = transport_->socket()->GetPeerAddress(&address);
    864   if (rv != OK)
    865     return rv;
    866   const struct addrinfo* ai = address.head();
    867   std::string peer_id(host_and_port_.ToString());
    868   peer_id += std::string(reinterpret_cast<char*>(ai->ai_addr),
    869                          ai->ai_addrlen);
    870   // SSLSetPeerID() treats peer_id as a binary blob, and makes its
    871   // own copy.
    872   status = SSLSetPeerID(ssl_context_, peer_id.data(), peer_id.length());
    873   if (status)
    874     return NetErrorFromOSStatus(status);
    875 
    876   return OK;
    877 }
    878 
    879 void SSLClientSocketMac::DoConnectCallback(int rv) {
    880   DCHECK(rv != ERR_IO_PENDING);
    881   DCHECK(user_connect_callback_);
    882 
    883   CompletionCallback* c = user_connect_callback_;
    884   user_connect_callback_ = NULL;
    885   c->Run(rv > OK ? OK : rv);
    886 }
    887 
    888 void SSLClientSocketMac::DoReadCallback(int rv) {
    889   DCHECK(rv != ERR_IO_PENDING);
    890   DCHECK(user_read_callback_);
    891 
    892   // Since Run may result in Read being called, clear user_read_callback_ up
    893   // front.
    894   CompletionCallback* c = user_read_callback_;
    895   user_read_callback_ = NULL;
    896   user_read_buf_ = NULL;
    897   user_read_buf_len_ = 0;
    898   c->Run(rv);
    899 }
    900 
    901 void SSLClientSocketMac::DoWriteCallback(int rv) {
    902   DCHECK(rv != ERR_IO_PENDING);
    903   DCHECK(user_write_callback_);
    904 
    905   // Since Run may result in Write being called, clear user_write_callback_ up
    906   // front.
    907   CompletionCallback* c = user_write_callback_;
    908   user_write_callback_ = NULL;
    909   user_write_buf_ = NULL;
    910   user_write_buf_len_ = 0;
    911   c->Run(rv);
    912 }
    913 
    914 void SSLClientSocketMac::OnHandshakeIOComplete(int result) {
    915   int rv = DoHandshakeLoop(result);
    916   if (rv != ERR_IO_PENDING) {
    917     // If there is no connect callback available to call, we are
    918     // renegotiating (which occurs because we are in the middle of a Read
    919     // when the renegotiation process starts).  So we complete the Read
    920     // here.
    921     if (!user_connect_callback_) {
    922       DoReadCallback(rv);
    923       return;
    924     }
    925     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
    926     DoConnectCallback(rv);
    927   }
    928 }
    929 
    930 void SSLClientSocketMac::OnTransportReadComplete(int result) {
    931   if (result > 0) {
    932     recv_buffer_.insert(recv_buffer_.end(),
    933                         read_io_buf_->data(),
    934                         read_io_buf_->data() + result);
    935   }
    936   read_io_buf_ = NULL;
    937 
    938   if (!completed_handshake()) {
    939     OnHandshakeIOComplete(result);
    940     return;
    941   }
    942 
    943   if (user_read_buf_) {
    944     if (result < 0) {
    945       DoReadCallback(result);
    946       return;
    947     }
    948     int rv = DoPayloadRead();
    949     if (rv != ERR_IO_PENDING)
    950       DoReadCallback(rv);
    951   }
    952 }
    953 
    954 void SSLClientSocketMac::OnTransportWriteComplete(int result) {
    955   write_io_buf_ = NULL;
    956 
    957   if (result < 0) {
    958     pending_send_error_ = result;
    959     return;
    960   }
    961 
    962   send_buffer_.erase(send_buffer_.begin(),
    963                      send_buffer_.begin() + result);
    964   if (!send_buffer_.empty())
    965     SSLWriteCallback(this, NULL, NULL);
    966 
    967   if (!completed_handshake()) {
    968     OnHandshakeIOComplete(result);
    969     return;
    970   }
    971 
    972   // If paused because too much data is in flight, try writing again and make
    973   // the promised callback.
    974   if (user_write_buf_ && send_buffer_.size() < kWriteSizeResumeLimit) {
    975     int rv = DoPayloadWrite();
    976     if (rv != ERR_IO_PENDING)
    977       DoWriteCallback(rv);
    978   }
    979 }
    980 
    981 int SSLClientSocketMac::DoHandshakeLoop(int last_io_result) {
    982   DCHECK(next_handshake_state_ != STATE_NONE);
    983   int rv = last_io_result;
    984   do {
    985     State state = next_handshake_state_;
    986     next_handshake_state_ = STATE_NONE;
    987     switch (state) {
    988       case STATE_HANDSHAKE:
    989         // Do the SSL/TLS handshake.
    990         rv = DoHandshake();
    991         break;
    992       case STATE_VERIFY_CERT:
    993         // Kick off server certificate validation.
    994         rv = DoVerifyCert();
    995         break;
    996       case STATE_VERIFY_CERT_COMPLETE:
    997         // Check the results of the server certificate validation.
    998         rv = DoVerifyCertComplete(rv);
    999         break;
   1000       case STATE_COMPLETED_RENEGOTIATION:
   1001         // The renegotiation handshake has completed, and the Read() call
   1002         // that was interrupted by the renegotiation needs to be resumed in
   1003         // order to to satisfy the original caller's request.
   1004         rv = DoCompletedRenegotiation(rv);
   1005         break;
   1006       case STATE_COMPLETED_HANDSHAKE:
   1007         next_handshake_state_ = STATE_COMPLETED_HANDSHAKE;
   1008         // This is the end of our state machine, so return.
   1009         return rv;
   1010       default:
   1011         rv = ERR_UNEXPECTED;
   1012         NOTREACHED() << "unexpected state";
   1013         break;
   1014     }
   1015   } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
   1016   return rv;
   1017 }
   1018 
   1019 int SSLClientSocketMac::DoHandshake() {
   1020   client_cert_requested_ = false;
   1021 
   1022   OSStatus status;
   1023   if (!renegotiating_) {
   1024     status = SSLHandshake(ssl_context_);
   1025   } else {
   1026     // Renegotiation can only be detected by a call to DoPayloadRead(),
   1027     // which means |user_read_buf_| should be valid.
   1028     DCHECK(user_read_buf_);
   1029 
   1030     // On OS X 10.5.x, SSLSetSessionOption with
   1031     // kSSLSessionOptionBreakOnServerAuth is broken for renegotiation, as
   1032     // SSLRead() does not internally handle errSSLServerAuthCompleted being
   1033     // returned during handshake. In order to support certificate validation
   1034     // after a renegotiation, SSLRead() sets |renegotiating_| to be true and
   1035     // returns errSSLWouldBlock when it detects an attempt to read the
   1036     // ServerHello after responding to a HelloRequest. It would be
   1037     // appropriate to call SSLHandshake() at this point to restart the
   1038     // handshake state machine, however, on 10.5.x, SSLHandshake() is buggy
   1039     // and will always return noErr (indicating handshake completion),
   1040     // without doing any actual work. Because of this, the only way to
   1041     // advance SecureTransport's internal handshake state machine is to
   1042     // continuously call SSLRead() until the handshake is marked complete.
   1043     // Once the handshake is completed, if it completed successfully, the
   1044     // user read callback is invoked with |bytes_read_after_renegotiation_|
   1045     // as the callback result. On 10.6.0+, both errSSLServerAuthCompleted
   1046     // and SSLHandshake() work as expected, so this strange workaround is
   1047     // only necessary while OS X 10.5.x is still supported.
   1048     bytes_read_after_renegotiation_ = 0;
   1049     status = SSLRead(ssl_context_, user_read_buf_->data(),
   1050                      user_read_buf_len_, &bytes_read_after_renegotiation_);
   1051     if (bytes_read_after_renegotiation_ > 0) {
   1052       // With SecureTransport, as of 10.6.5, if application data is read,
   1053       // then the handshake should be completed. This is because
   1054       // SecureTransport does not (yet) support exchanging application data
   1055       // in the midst of handshakes. This is permitted in the TLS
   1056       // specification, as peers may exchange messages using the previous
   1057       // cipher spec up until they exchange ChangeCipherSpec messages.
   1058       // However, in addition to SecureTransport not supporting this, we do
   1059       // not permit callers to enter Read() or Write() when a handshake is
   1060       // occurring, in part due to the deception that happens in
   1061       // SSLWriteCallback(). Thus we need to make sure the handshake is
   1062       // truly completed before processing application data, and if any was
   1063       // read before the handshake is completed, it will be dropped and the
   1064       // connection aborted.
   1065       SSLSessionState session_state = kSSLIdle;
   1066       status = SSLGetSessionState(ssl_context_, &session_state);
   1067       if (session_state != kSSLConnected)
   1068         status = errSSLProtocol;
   1069     }
   1070   }
   1071 
   1072   SSLClientCertificateState client_cert_state;
   1073   if (SSLGetClientCertificateState(ssl_context_, &client_cert_state) != noErr)
   1074     client_cert_state = kSSLClientCertNone;
   1075   if (client_cert_state > kSSLClientCertNone)
   1076     client_cert_requested_ = true;
   1077 
   1078   int net_error = ERR_FAILED;
   1079   switch (status) {
   1080     case noErr:
   1081       return DidCompleteHandshake();
   1082     case errSSLWouldBlock:
   1083       next_handshake_state_ = STATE_HANDSHAKE;
   1084       return ERR_IO_PENDING;
   1085     case errSSLClosedGraceful:
   1086       // The server unexpectedly closed on us.
   1087       net_error = ERR_SSL_PROTOCOL_ERROR;
   1088       break;
   1089     case errSSLClosedAbort:
   1090     case errSSLPeerHandshakeFail:
   1091       if (client_cert_requested_) {
   1092         if (!ssl_config_.send_client_cert) {
   1093           // The server aborted, likely due to requiring a client certificate
   1094           // and one wasn't sent.
   1095           VLOG(1) << "Server requested SSL cert during handshake";
   1096           net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
   1097         } else {
   1098           // The server aborted, likely due to not liking the client
   1099           // certificate that was sent.
   1100           LOG(WARNING) << "Server aborted SSL handshake";
   1101           net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT;
   1102         }
   1103         // Don't fall through - the error was intentionally remapped.
   1104         break;
   1105       }
   1106       // Fall through if a client cert wasn't requested.
   1107     default:
   1108       net_error = NetErrorFromOSStatus(status);
   1109       DCHECK(!IsCertificateError(net_error));
   1110       if (!ssl_config_.send_client_cert &&
   1111          (client_cert_state == kSSLClientCertRejected ||
   1112           net_error == ERR_BAD_SSL_CLIENT_AUTH_CERT)) {
   1113         // The server unexpectedly sent a peer certificate error alert when no
   1114         // certificate had been sent.
   1115         net_error = ERR_SSL_PROTOCOL_ERROR;
   1116       }
   1117       break;
   1118   }
   1119 
   1120   net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
   1121                     new SSLErrorParams(net_error, status));
   1122   return net_error;
   1123 }
   1124 
   1125 int SSLClientSocketMac::DoVerifyCert() {
   1126   next_handshake_state_ = STATE_VERIFY_CERT_COMPLETE;
   1127 
   1128   DCHECK(server_cert_);
   1129 
   1130   VLOG(1) << "DoVerifyCert...";
   1131   int flags = 0;
   1132   if (ssl_config_.rev_checking_enabled)
   1133     flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
   1134   if (ssl_config_.verify_ev_cert)
   1135     flags |= X509Certificate::VERIFY_EV_CERT;
   1136   verifier_.reset(new SingleRequestCertVerifier(cert_verifier_));
   1137   return verifier_->Verify(server_cert_, host_and_port_.host(), flags,
   1138                            &server_cert_verify_result_,
   1139                            &handshake_io_callback_);
   1140 }
   1141 
   1142 int SSLClientSocketMac::DoVerifyCertComplete(int result) {
   1143   DCHECK(verifier_.get());
   1144   verifier_.reset();
   1145 
   1146   VLOG(1) << "...DoVerifyCertComplete (result=" << result << ")";
   1147   if (IsCertificateError(result) && ssl_config_.IsAllowedBadCert(server_cert_))
   1148     result = OK;
   1149 
   1150   if (result == OK && client_cert_requested_ &&
   1151       !ssl_config_.send_client_cert) {
   1152     // Caller hasn't specified a client cert, so let it know the server is
   1153     // asking for one, and abort the connection.
   1154     return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
   1155   }
   1156   VLOG(1) << "Handshake finished! (DoVerifyCertComplete)";
   1157 
   1158   if (renegotiating_) {
   1159     DidCompleteRenegotiation();
   1160     return result;
   1161   }
   1162 
   1163   // The initial handshake has completed.
   1164   next_handshake_state_ = STATE_COMPLETED_HANDSHAKE;
   1165 
   1166   return result;
   1167 }
   1168 
   1169 int SSLClientSocketMac::SetClientCert() {
   1170   if (!ssl_config_.send_client_cert || !ssl_config_.client_cert)
   1171     return noErr;
   1172 
   1173   base::mac::ScopedCFTypeRef<CFArrayRef> cert_refs(
   1174       ssl_config_.client_cert->CreateClientCertificateChain());
   1175   VLOG(1) << "SSLSetCertificate(" << CFArrayGetCount(cert_refs) << " certs)";
   1176   OSStatus result = SSLSetCertificate(ssl_context_, cert_refs);
   1177   if (result)
   1178     LOG(ERROR) << "SSLSetCertificate returned OSStatus " << result;
   1179   return result;
   1180 }
   1181 
   1182 int SSLClientSocketMac::DoPayloadRead() {
   1183   size_t processed = 0;
   1184   OSStatus status = SSLRead(ssl_context_, user_read_buf_->data(),
   1185                             user_read_buf_len_, &processed);
   1186   if (status == errSSLWouldBlock && renegotiating_) {
   1187     CHECK_EQ(static_cast<size_t>(0), processed);
   1188     next_handshake_state_ = STATE_HANDSHAKE;
   1189     return DoHandshakeLoop(OK);
   1190   }
   1191   // There's a subtle difference here in semantics of the "would block" errors.
   1192   // In our code, ERR_IO_PENDING means the whole operation is async, while
   1193   // errSSLWouldBlock means that the stream isn't ending (and is often returned
   1194   // along with partial data). So even though "would block" is returned, if we
   1195   // have data, let's just return it. This is further complicated by the fact
   1196   // that errSSLWouldBlock is also used to short-circuit SSLRead()'s
   1197   // transparent renegotiation, so that we can update our state machine above,
   1198   // which otherwise would get out of sync with the SSLContextRef's internal
   1199   // state machine.
   1200   if (processed > 0)
   1201     return processed;
   1202 
   1203   switch (status) {
   1204     case errSSLClosedNoNotify:
   1205       // TODO(wtc): Unless we have received the close_notify alert, we need to
   1206       // return an error code indicating that the SSL connection ended
   1207       // uncleanly, a potential truncation attack.  See http://crbug.com/18586.
   1208       return OK;
   1209 
   1210     default:
   1211       return NetErrorFromOSStatus(status);
   1212   }
   1213 }
   1214 
   1215 int SSLClientSocketMac::DoPayloadWrite() {
   1216   // Too much data in flight?
   1217   if (send_buffer_.size() > kWriteSizePauseLimit)
   1218     return ERR_IO_PENDING;
   1219 
   1220   size_t processed = 0;
   1221   OSStatus status = SSLWrite(ssl_context_,
   1222                              user_write_buf_->data(),
   1223                              user_write_buf_len_,
   1224                              &processed);
   1225 
   1226   if (processed > 0)
   1227     return processed;
   1228 
   1229   return NetErrorFromOSStatus(status);
   1230 }
   1231 
   1232 int SSLClientSocketMac::DoCompletedRenegotiation(int result) {
   1233   // The user had a read in progress, which was interrupted by the
   1234   // renegotiation. Return the application data that was processed after the
   1235   // handshake completed.
   1236   next_handshake_state_ = STATE_COMPLETED_HANDSHAKE;
   1237   if (result != OK)
   1238     return result;
   1239   return bytes_read_after_renegotiation_;
   1240 }
   1241 
   1242 void SSLClientSocketMac::DidCompleteRenegotiation() {
   1243   DCHECK(!user_connect_callback_);
   1244   renegotiating_ = false;
   1245   next_handshake_state_ = STATE_COMPLETED_RENEGOTIATION;
   1246 }
   1247 
   1248 int SSLClientSocketMac::DidCompleteHandshake() {
   1249   DCHECK(!server_cert_ || renegotiating_);
   1250   VLOG(1) << "Handshake completed, next verify cert";
   1251 
   1252   scoped_refptr<X509Certificate> new_server_cert(
   1253       GetServerCert(ssl_context_));
   1254   if (!new_server_cert)
   1255     return ERR_UNEXPECTED;
   1256 
   1257   if (renegotiating_ &&
   1258       X509Certificate::IsSameOSCert(server_cert_->os_cert_handle(),
   1259                                     new_server_cert->os_cert_handle())) {
   1260     // We already verified the server certificate.  Either it is good or the
   1261     // user has accepted the certificate error.
   1262     DidCompleteRenegotiation();
   1263   } else {
   1264     server_cert_ = new_server_cert;
   1265     next_handshake_state_ = STATE_VERIFY_CERT;
   1266   }
   1267   return OK;
   1268 }
   1269 
   1270 // static
   1271 OSStatus SSLClientSocketMac::SSLReadCallback(SSLConnectionRef connection,
   1272                                              void* data,
   1273                                              size_t* data_length) {
   1274   DCHECK(data);
   1275   DCHECK(data_length);
   1276   SSLClientSocketMac* us =
   1277       const_cast<SSLClientSocketMac*>(
   1278           static_cast<const SSLClientSocketMac*>(connection));
   1279 
   1280   if (us->read_io_buf_) {
   1281     // We have I/O in flight; promise we'll get back to them and use the
   1282     // existing callback to do so.
   1283     *data_length = 0;
   1284     return errSSLWouldBlock;
   1285   }
   1286   if (us->completed_handshake()) {
   1287     // The state machine for SSLRead, located in libsecurity_ssl's
   1288     // sslTransport.c, will attempt to fully complete the renegotiation
   1289     // transparently in SSLRead once it reads the server's HelloRequest
   1290     // message. In order to make sure that the server certificate is
   1291     // (re-)verified and that any other parameters are logged (eg:
   1292     // certificate request state), we try to detect that the
   1293     // SSLClientSocketMac's state machine is out of sync with the
   1294     // SSLContext's. When that happens, we break out by faking
   1295     // errSSLWouldBlock, and set a flag so that DoPayloadRead() knows that
   1296     // it's not actually blocked. DoPayloadRead() will then restart the
   1297     // handshake state machine, and finally resume the original Read()
   1298     // once it successfully completes, similar to the behaviour of
   1299     // SSLClientSocketWin's DoDecryptPayload() and DoLoop() behave.
   1300     SSLSessionState state;
   1301     OSStatus status = SSLGetSessionState(us->ssl_context_, &state);
   1302     if (status) {
   1303       *data_length = 0;
   1304       return status;
   1305     }
   1306     if (state == kSSLHandshake) {
   1307       *data_length = 0;
   1308       us->renegotiating_ = true;
   1309       return errSSLWouldBlock;
   1310     }
   1311   }
   1312 
   1313   size_t total_read = us->recv_buffer_.size();
   1314 
   1315   int rv = 1;  // any old value to spin the loop below
   1316   while (rv > 0 && total_read < *data_length) {
   1317     us->read_io_buf_ = new IOBuffer(*data_length - total_read);
   1318     rv = us->transport_->socket()->Read(us->read_io_buf_,
   1319                                         *data_length - total_read,
   1320                                         &us->transport_read_callback_);
   1321 
   1322     if (rv >= 0) {
   1323       us->recv_buffer_.insert(us->recv_buffer_.end(),
   1324                               us->read_io_buf_->data(),
   1325                               us->read_io_buf_->data() + rv);
   1326       us->read_io_buf_ = NULL;
   1327       total_read += rv;
   1328     }
   1329   }
   1330 
   1331   *data_length = total_read;
   1332   if (total_read) {
   1333     memcpy(data, &us->recv_buffer_[0], total_read);
   1334     us->recv_buffer_.clear();
   1335   }
   1336 
   1337   if (rv != ERR_IO_PENDING)
   1338     us->read_io_buf_ = NULL;
   1339 
   1340   if (rv < 0)
   1341     return OSStatusFromNetError(rv);
   1342   else if (rv == 0)  // stream closed
   1343     return errSSLClosedGraceful;
   1344   else
   1345     return noErr;
   1346 }
   1347 
   1348 // static
   1349 OSStatus SSLClientSocketMac::SSLWriteCallback(SSLConnectionRef connection,
   1350                                               const void* data,
   1351                                               size_t* data_length) {
   1352   SSLClientSocketMac* us =
   1353       const_cast<SSLClientSocketMac*>(
   1354           static_cast<const SSLClientSocketMac*>(connection));
   1355 
   1356   if (us->pending_send_error_ != OK) {
   1357     OSStatus status = OSStatusFromNetError(us->pending_send_error_);
   1358     us->pending_send_error_ = OK;
   1359     return status;
   1360   }
   1361 
   1362   if (data)
   1363     us->send_buffer_.insert(us->send_buffer_.end(),
   1364                             static_cast<const char*>(data),
   1365                             static_cast<const char*>(data) + *data_length);
   1366 
   1367   if (us->write_io_buf_) {
   1368     // If we have I/O in flight, just add the data to the end of the buffer and
   1369     // return to our caller. The existing callback will trigger the write of the
   1370     // new data when it sees that data remains in the buffer after removing the
   1371     // sent data. As always, lie to our caller.
   1372     return noErr;
   1373   }
   1374 
   1375   int rv;
   1376   do {
   1377     us->write_io_buf_ = new IOBuffer(us->send_buffer_.size());
   1378     memcpy(us->write_io_buf_->data(), &us->send_buffer_[0],
   1379            us->send_buffer_.size());
   1380     rv = us->transport_->socket()->Write(us->write_io_buf_,
   1381                                          us->send_buffer_.size(),
   1382                                          &us->transport_write_callback_);
   1383     if (rv > 0) {
   1384       us->send_buffer_.erase(us->send_buffer_.begin(),
   1385                              us->send_buffer_.begin() + rv);
   1386       us->write_io_buf_ = NULL;
   1387     }
   1388   } while (rv > 0 && !us->send_buffer_.empty());
   1389 
   1390   if (rv < 0 && rv != ERR_IO_PENDING) {
   1391     us->write_io_buf_ = NULL;
   1392     return OSStatusFromNetError(rv);
   1393   }
   1394 
   1395   // always lie to our caller
   1396   return noErr;
   1397 }
   1398 
   1399 }  // namespace net
   1400