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
102namespace net {
103
104namespace {
105
106// Pause if we have 2MB of data in flight, resume once we're down below 1MB.
107const unsigned int kWriteSizePauseLimit = 2 * 1024 * 1024;
108const 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.
113enum {
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
145int 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
222OSStatus 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?
253int 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.
366bool 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.
416X509Certificate* 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.
446template <typename FNTYPE>
447FNTYPE 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
455struct 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.
473class 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
487static base::LazyInstance<EnabledCipherSuites> g_enabled_cipher_suites(
488    base::LINKER_INITIALIZED);
489
490EnabledCipherSuites::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
521SSLClientSocketMac::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
553SSLClientSocketMac::~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
561int 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
588void 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
603bool 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
613bool 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
625int SSLClientSocketMac::GetPeerAddress(AddressList* address) const {
626  return transport_->socket()->GetPeerAddress(address);
627}
628
629int SSLClientSocketMac::GetLocalAddress(IPEndPoint* address) const {
630  return transport_->socket()->GetLocalAddress(address);
631}
632
633const BoundNetLog& SSLClientSocketMac::NetLog() const {
634  return net_log_;
635}
636
637void SSLClientSocketMac::SetSubresourceSpeculation() {
638  if (transport_.get() && transport_->socket()) {
639    transport_->socket()->SetSubresourceSpeculation();
640  } else {
641    NOTREACHED();
642  }
643}
644
645void SSLClientSocketMac::SetOmniboxSpeculation() {
646  if (transport_.get() && transport_->socket()) {
647    transport_->socket()->SetOmniboxSpeculation();
648  } else {
649    NOTREACHED();
650  }
651}
652
653bool SSLClientSocketMac::WasEverUsed() const {
654  if (transport_.get() && transport_->socket()) {
655    return transport_->socket()->WasEverUsed();
656  }
657  NOTREACHED();
658  return false;
659}
660
661bool SSLClientSocketMac::UsingTCPFastOpen() const {
662  if (transport_.get() && transport_->socket()) {
663    return transport_->socket()->UsingTCPFastOpen();
664  }
665  NOTREACHED();
666  return false;
667}
668
669int 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
688int 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
707bool SSLClientSocketMac::SetReceiveBufferSize(int32 size) {
708  return transport_->socket()->SetReceiveBufferSize(size);
709}
710
711bool SSLClientSocketMac::SetSendBufferSize(int32 size) {
712  return transport_->socket()->SetSendBufferSize(size);
713}
714
715void 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
742void 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
778SSLClientSocket::NextProtoStatus
779SSLClientSocketMac::GetNextProto(std::string* proto) {
780  proto->clear();
781  return kNextProtoUnsupported;
782}
783
784int 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
879void 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
888void 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
901void 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
914void 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
930void 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
954void 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
981int 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
1019int 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
1125int 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
1142int 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
1169int 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
1182int 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
1215int 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
1232int 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
1242void SSLClientSocketMac::DidCompleteRenegotiation() {
1243  DCHECK(!user_connect_callback_);
1244  renegotiating_ = false;
1245  next_handshake_state_ = STATE_COMPLETED_RENEGOTIATION;
1246}
1247
1248int 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
1271OSStatus 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
1349OSStatus 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