• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
NetErrorFromOSStatus(OSStatus status)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 
OSStatusFromNetError(int net_error)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?
KeySizeOfCipherSuite(SSLCipherSuite suite)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.
ShouldEnableCipherSuite(SSLCipherSuite suite)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.
GetServerCert(SSLContextRef ssl_context)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>
LookupFunction(CFStringRef bundleName,CFStringRef fnName)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 {
CipherSuiteIsDisabledFunctornet::__anon804929940111::CipherSuiteIsDisabledFunctor456   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|.
operator ()net::__anon804929940111::CipherSuiteIsDisabledFunctor462   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:
ciphers() const475   const std::vector<SSLCipherSuite>& ciphers() const { return ciphers_; }
476 
477  private:
478   friend struct base::DefaultLazyInstanceTraits<EnabledCipherSuites>;
479   EnabledCipherSuites();
~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 
EnabledCipherSuites()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 
SSLClientSocketMac(ClientSocketHandle * transport_socket,const HostPortPair & host_and_port,const SSLConfig & ssl_config,CertVerifier * cert_verifier)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 
~SSLClientSocketMac()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
Connect(CompletionCallback * callback,bool wait_for_connect)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 
Disconnect()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 
IsConnected() const603 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 
IsConnectedAndIdle() const613 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 
GetPeerAddress(AddressList * address) const625 int SSLClientSocketMac::GetPeerAddress(AddressList* address) const {
626   return transport_->socket()->GetPeerAddress(address);
627 }
628 
GetLocalAddress(IPEndPoint * address) const629 int SSLClientSocketMac::GetLocalAddress(IPEndPoint* address) const {
630   return transport_->socket()->GetLocalAddress(address);
631 }
632 
NetLog() const633 const BoundNetLog& SSLClientSocketMac::NetLog() const {
634   return net_log_;
635 }
636 
SetSubresourceSpeculation()637 void SSLClientSocketMac::SetSubresourceSpeculation() {
638   if (transport_.get() && transport_->socket()) {
639     transport_->socket()->SetSubresourceSpeculation();
640   } else {
641     NOTREACHED();
642   }
643 }
644 
SetOmniboxSpeculation()645 void SSLClientSocketMac::SetOmniboxSpeculation() {
646   if (transport_.get() && transport_->socket()) {
647     transport_->socket()->SetOmniboxSpeculation();
648   } else {
649     NOTREACHED();
650   }
651 }
652 
WasEverUsed() const653 bool SSLClientSocketMac::WasEverUsed() const {
654   if (transport_.get() && transport_->socket()) {
655     return transport_->socket()->WasEverUsed();
656   }
657   NOTREACHED();
658   return false;
659 }
660 
UsingTCPFastOpen() const661 bool SSLClientSocketMac::UsingTCPFastOpen() const {
662   if (transport_.get() && transport_->socket()) {
663     return transport_->socket()->UsingTCPFastOpen();
664   }
665   NOTREACHED();
666   return false;
667 }
668 
Read(IOBuffer * buf,int buf_len,CompletionCallback * callback)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 
Write(IOBuffer * buf,int buf_len,CompletionCallback * callback)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 
SetReceiveBufferSize(int32 size)707 bool SSLClientSocketMac::SetReceiveBufferSize(int32 size) {
708   return transport_->socket()->SetReceiveBufferSize(size);
709 }
710 
SetSendBufferSize(int32 size)711 bool SSLClientSocketMac::SetSendBufferSize(int32 size) {
712   return transport_->socket()->SetSendBufferSize(size);
713 }
714 
GetSSLInfo(SSLInfo * ssl_info)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 
GetSSLCertRequestInfo(SSLCertRequestInfo * cert_request_info)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
GetNextProto(std::string * proto)779 SSLClientSocketMac::GetNextProto(std::string* proto) {
780   proto->clear();
781   return kNextProtoUnsupported;
782 }
783 
InitializeSSLContext()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 
DoConnectCallback(int rv)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 
DoReadCallback(int rv)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 
DoWriteCallback(int rv)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 
OnHandshakeIOComplete(int result)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 
OnTransportReadComplete(int result)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 
OnTransportWriteComplete(int result)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 
DoHandshakeLoop(int last_io_result)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 
DoHandshake()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 
DoVerifyCert()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 
DoVerifyCertComplete(int result)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 
SetClientCert()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 
DoPayloadRead()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 
DoPayloadWrite()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 
DoCompletedRenegotiation(int result)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 
DidCompleteRenegotiation()1242 void SSLClientSocketMac::DidCompleteRenegotiation() {
1243   DCHECK(!user_connect_callback_);
1244   renegotiating_ = false;
1245   next_handshake_state_ = STATE_COMPLETED_RENEGOTIATION;
1246 }
1247 
DidCompleteHandshake()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
SSLReadCallback(SSLConnectionRef connection,void * data,size_t * data_length)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
SSLWriteCallback(SSLConnectionRef connection,const void * data,size_t * data_length)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