• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
9  * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
10  *
11  * This software is licensed as described in the file COPYING, which
12  * you should have received as part of this distribution. The terms
13  * are also available at https://curl.haxx.se/docs/copyright.html.
14  *
15  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16  * copies of the Software, and permit persons to whom the Software is
17  * furnished to do so, under the terms of the COPYING file.
18  *
19  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20  * KIND, either express or implied.
21  *
22  ***************************************************************************/
23 
24 /*
25  * Source file for all iOS and macOS SecureTransport-specific code for the
26  * TLS/SSL layer. No code but vtls.c should ever call or use these functions.
27  */
28 
29 #include "curl_setup.h"
30 
31 #include "urldata.h" /* for the Curl_easy definition */
32 #include "curl_base64.h"
33 #include "strtok.h"
34 
35 #ifdef USE_DARWINSSL
36 
37 #ifdef __clang__
38 #pragma clang diagnostic push
39 #pragma clang diagnostic ignored "-Wtautological-pointer-compare"
40 #endif /* __clang__ */
41 
42 #include <limits.h>
43 
44 #include <Security/Security.h>
45 /* For some reason, when building for iOS, the omnibus header above does
46  * not include SecureTransport.h as of iOS SDK 5.1. */
47 #include <Security/SecureTransport.h>
48 #include <CoreFoundation/CoreFoundation.h>
49 #include <CommonCrypto/CommonDigest.h>
50 
51 /* The Security framework has changed greatly between iOS and different macOS
52    versions, and we will try to support as many of them as we can (back to
53    Leopard and iOS 5) by using macros and weak-linking.
54 
55    In general, you want to build this using the most recent OS SDK, since some
56    features require curl to be built against the latest SDK. TLS 1.1 and 1.2
57    support, for instance, require the macOS 10.8 SDK or later. TLS 1.3
58    requires the macOS 10.13 or iOS 11 SDK or later. */
59 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
60 
61 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
62 #error "The darwinssl back-end requires Leopard or later."
63 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
64 
65 #define CURL_BUILD_IOS 0
66 #define CURL_BUILD_IOS_7 0
67 #define CURL_BUILD_IOS_11 0
68 #define CURL_BUILD_MAC 1
69 /* This is the maximum API level we are allowed to use when building: */
70 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
71 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
72 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
73 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
74 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
75 #define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
76 /* These macros mean "the following code is present to allow runtime backward
77    compatibility with at least this cat or earlier":
78    (You set this at build-time using the compiler command line option
79    "-mmacos-version-min.") */
80 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
81 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
82 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
83 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
84 #define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
85 
86 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
87 #define CURL_BUILD_IOS 1
88 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
89 #define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
90 #define CURL_BUILD_MAC 0
91 #define CURL_BUILD_MAC_10_5 0
92 #define CURL_BUILD_MAC_10_6 0
93 #define CURL_BUILD_MAC_10_7 0
94 #define CURL_BUILD_MAC_10_8 0
95 #define CURL_BUILD_MAC_10_9 0
96 #define CURL_BUILD_MAC_10_13 0
97 #define CURL_SUPPORT_MAC_10_5 0
98 #define CURL_SUPPORT_MAC_10_6 0
99 #define CURL_SUPPORT_MAC_10_7 0
100 #define CURL_SUPPORT_MAC_10_8 0
101 #define CURL_SUPPORT_MAC_10_9 0
102 
103 #else
104 #error "The darwinssl back-end requires iOS or OS X."
105 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
106 
107 #if CURL_BUILD_MAC
108 #include <sys/sysctl.h>
109 #endif /* CURL_BUILD_MAC */
110 
111 #include "urldata.h"
112 #include "sendf.h"
113 #include "inet_pton.h"
114 #include "connect.h"
115 #include "select.h"
116 #include "vtls.h"
117 #include "darwinssl.h"
118 #include "curl_printf.h"
119 
120 #include "curl_memory.h"
121 /* The last #include file should be: */
122 #include "memdebug.h"
123 
124 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
125 #define ioErr -36
126 #define paramErr -50
127 
128 struct ssl_backend_data {
129   SSLContextRef ssl_ctx;
130   curl_socket_t ssl_sockfd;
131   bool ssl_direction; /* true if writing, false if reading */
132   size_t ssl_write_buffered_length;
133 };
134 
135 #define BACKEND connssl->backend
136 
137 /* pinned public key support tests */
138 
139 /* version 1 supports macOS 10.12+ and iOS 10+ */
140 #if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \
141     (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED  >= 101200))
142 #define DARWIN_SSL_PINNEDPUBKEY_V1 1
143 #endif
144 
145 /* version 2 supports MacOSX 10.7+ */
146 #if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
147 #define DARWIN_SSL_PINNEDPUBKEY_V2 1
148 #endif
149 
150 #if defined(DARWIN_SSL_PINNEDPUBKEY_V1) || defined(DARWIN_SSL_PINNEDPUBKEY_V2)
151 /* this backend supports CURLOPT_PINNEDPUBLICKEY */
152 #define DARWIN_SSL_PINNEDPUBKEY 1
153 #endif /* DARWIN_SSL_PINNEDPUBKEY */
154 
155 #ifdef DARWIN_SSL_PINNEDPUBKEY
156 /* both new and old APIs return rsa keys missing the spki header (not DER) */
157 static const unsigned char rsa4096SpkiHeader[] = {
158                                        0x30, 0x82, 0x02, 0x22, 0x30, 0x0d,
159                                        0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
160                                        0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
161                                        0x00, 0x03, 0x82, 0x02, 0x0f, 0x00};
162 
163 static const unsigned char rsa2048SpkiHeader[] = {
164                                        0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
165                                        0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
166                                        0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
167                                        0x00, 0x03, 0x82, 0x01, 0x0f, 0x00};
168 #ifdef DARWIN_SSL_PINNEDPUBKEY_V1
169 /* the *new* version doesn't return DER encoded ecdsa certs like the old... */
170 static const unsigned char ecDsaSecp256r1SpkiHeader[] = {
171                                        0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
172                                        0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
173                                        0x01, 0x06, 0x08, 0x2a, 0x86, 0x48,
174                                        0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
175                                        0x42, 0x00};
176 
177 static const unsigned char ecDsaSecp384r1SpkiHeader[] = {
178                                        0x30, 0x76, 0x30, 0x10, 0x06, 0x07,
179                                        0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
180                                        0x01, 0x06, 0x05, 0x2b, 0x81, 0x04,
181                                        0x00, 0x22, 0x03, 0x62, 0x00};
182 #endif /* DARWIN_SSL_PINNEDPUBKEY_V1 */
183 #endif /* DARWIN_SSL_PINNEDPUBKEY */
184 
185 /* The following two functions were ripped from Apple sample code,
186  * with some modifications: */
SocketRead(SSLConnectionRef connection,void * data,size_t * dataLength)187 static OSStatus SocketRead(SSLConnectionRef connection,
188                            void *data,          /* owned by
189                                                  * caller, data
190                                                  * RETURNED */
191                            size_t *dataLength)  /* IN/OUT */
192 {
193   size_t bytesToGo = *dataLength;
194   size_t initLen = bytesToGo;
195   UInt8 *currData = (UInt8 *)data;
196   /*int sock = *(int *)connection;*/
197   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
198   int sock = BACKEND->ssl_sockfd;
199   OSStatus rtn = noErr;
200   size_t bytesRead;
201   ssize_t rrtn;
202   int theErr;
203 
204   *dataLength = 0;
205 
206   for(;;) {
207     bytesRead = 0;
208     rrtn = read(sock, currData, bytesToGo);
209     if(rrtn <= 0) {
210       /* this is guesswork... */
211       theErr = errno;
212       if(rrtn == 0) { /* EOF = server hung up */
213         /* the framework will turn this into errSSLClosedNoNotify */
214         rtn = errSSLClosedGraceful;
215       }
216       else /* do the switch */
217         switch(theErr) {
218           case ENOENT:
219             /* connection closed */
220             rtn = errSSLClosedGraceful;
221             break;
222           case ECONNRESET:
223             rtn = errSSLClosedAbort;
224             break;
225           case EAGAIN:
226             rtn = errSSLWouldBlock;
227             BACKEND->ssl_direction = false;
228             break;
229           default:
230             rtn = ioErr;
231             break;
232         }
233       break;
234     }
235     else {
236       bytesRead = rrtn;
237     }
238     bytesToGo -= bytesRead;
239     currData  += bytesRead;
240 
241     if(bytesToGo == 0) {
242       /* filled buffer with incoming data, done */
243       break;
244     }
245   }
246   *dataLength = initLen - bytesToGo;
247 
248   return rtn;
249 }
250 
SocketWrite(SSLConnectionRef connection,const void * data,size_t * dataLength)251 static OSStatus SocketWrite(SSLConnectionRef connection,
252                             const void *data,
253                             size_t *dataLength)  /* IN/OUT */
254 {
255   size_t bytesSent = 0;
256   /*int sock = *(int *)connection;*/
257   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
258   int sock = BACKEND->ssl_sockfd;
259   ssize_t length;
260   size_t dataLen = *dataLength;
261   const UInt8 *dataPtr = (UInt8 *)data;
262   OSStatus ortn;
263   int theErr;
264 
265   *dataLength = 0;
266 
267   do {
268     length = write(sock,
269                    (char *)dataPtr + bytesSent,
270                    dataLen - bytesSent);
271   } while((length > 0) &&
272            ( (bytesSent += length) < dataLen) );
273 
274   if(length <= 0) {
275     theErr = errno;
276     if(theErr == EAGAIN) {
277       ortn = errSSLWouldBlock;
278       BACKEND->ssl_direction = true;
279     }
280     else {
281       ortn = ioErr;
282     }
283   }
284   else {
285     ortn = noErr;
286   }
287   *dataLength = bytesSent;
288   return ortn;
289 }
290 
291 #ifndef CURL_DISABLE_VERBOSE_STRINGS
SSLCipherNameForNumber(SSLCipherSuite cipher)292 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher)
293 {
294   switch(cipher) {
295     /* SSL version 3.0 */
296     case SSL_RSA_WITH_NULL_MD5:
297       return "SSL_RSA_WITH_NULL_MD5";
298       break;
299     case SSL_RSA_WITH_NULL_SHA:
300       return "SSL_RSA_WITH_NULL_SHA";
301       break;
302     case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
303       return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
304       break;
305     case SSL_RSA_WITH_RC4_128_MD5:
306       return "SSL_RSA_WITH_RC4_128_MD5";
307       break;
308     case SSL_RSA_WITH_RC4_128_SHA:
309       return "SSL_RSA_WITH_RC4_128_SHA";
310       break;
311     case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
312       return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
313       break;
314     case SSL_RSA_WITH_IDEA_CBC_SHA:
315       return "SSL_RSA_WITH_IDEA_CBC_SHA";
316       break;
317     case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
318       return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
319       break;
320     case SSL_RSA_WITH_DES_CBC_SHA:
321       return "SSL_RSA_WITH_DES_CBC_SHA";
322       break;
323     case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
324       return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
325       break;
326     case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
327       return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
328       break;
329     case SSL_DH_DSS_WITH_DES_CBC_SHA:
330       return "SSL_DH_DSS_WITH_DES_CBC_SHA";
331       break;
332     case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
333       return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
334       break;
335     case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
336       return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
337       break;
338     case SSL_DH_RSA_WITH_DES_CBC_SHA:
339       return "SSL_DH_RSA_WITH_DES_CBC_SHA";
340       break;
341     case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
342       return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
343       break;
344     case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
345       return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
346       break;
347     case SSL_DHE_DSS_WITH_DES_CBC_SHA:
348       return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
349       break;
350     case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
351       return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
352       break;
353     case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
354       return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
355       break;
356     case SSL_DHE_RSA_WITH_DES_CBC_SHA:
357       return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
358       break;
359     case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
360       return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
361       break;
362     case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
363       return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
364       break;
365     case SSL_DH_anon_WITH_RC4_128_MD5:
366       return "SSL_DH_anon_WITH_RC4_128_MD5";
367       break;
368     case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
369       return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
370       break;
371     case SSL_DH_anon_WITH_DES_CBC_SHA:
372       return "SSL_DH_anon_WITH_DES_CBC_SHA";
373       break;
374     case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
375       return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
376       break;
377     case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
378       return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
379       break;
380     case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
381       return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
382       break;
383     /* TLS 1.0 with AES (RFC 3268)
384        (Apparently these are used in SSLv3 implementations as well.) */
385     case TLS_RSA_WITH_AES_128_CBC_SHA:
386       return "TLS_RSA_WITH_AES_128_CBC_SHA";
387       break;
388     case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
389       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
390       break;
391     case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
392       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
393       break;
394     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
395       return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
396       break;
397     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
398       return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
399       break;
400     case TLS_DH_anon_WITH_AES_128_CBC_SHA:
401       return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
402       break;
403     case TLS_RSA_WITH_AES_256_CBC_SHA:
404       return "TLS_RSA_WITH_AES_256_CBC_SHA";
405       break;
406     case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
407       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
408       break;
409     case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
410       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
411       break;
412     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
413       return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
414       break;
415     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
416       return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
417       break;
418     case TLS_DH_anon_WITH_AES_256_CBC_SHA:
419       return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
420       break;
421     /* SSL version 2.0 */
422     case SSL_RSA_WITH_RC2_CBC_MD5:
423       return "SSL_RSA_WITH_RC2_CBC_MD5";
424       break;
425     case SSL_RSA_WITH_IDEA_CBC_MD5:
426       return "SSL_RSA_WITH_IDEA_CBC_MD5";
427       break;
428     case SSL_RSA_WITH_DES_CBC_MD5:
429       return "SSL_RSA_WITH_DES_CBC_MD5";
430       break;
431     case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
432       return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
433       break;
434   }
435   return "SSL_NULL_WITH_NULL_NULL";
436 }
437 
TLSCipherNameForNumber(SSLCipherSuite cipher)438 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
439 {
440   switch(cipher) {
441     /* TLS 1.0 with AES (RFC 3268) */
442     case TLS_RSA_WITH_AES_128_CBC_SHA:
443       return "TLS_RSA_WITH_AES_128_CBC_SHA";
444       break;
445     case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
446       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
447       break;
448     case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
449       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
450       break;
451     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
452       return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
453       break;
454     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
455       return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
456       break;
457     case TLS_DH_anon_WITH_AES_128_CBC_SHA:
458       return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
459       break;
460     case TLS_RSA_WITH_AES_256_CBC_SHA:
461       return "TLS_RSA_WITH_AES_256_CBC_SHA";
462       break;
463     case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
464       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
465       break;
466     case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
467       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
468       break;
469     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
470       return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
471       break;
472     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
473       return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
474       break;
475     case TLS_DH_anon_WITH_AES_256_CBC_SHA:
476       return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
477       break;
478 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
479     /* TLS 1.0 with ECDSA (RFC 4492) */
480     case TLS_ECDH_ECDSA_WITH_NULL_SHA:
481       return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
482       break;
483     case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
484       return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
485       break;
486     case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
487       return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
488       break;
489     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
490       return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
491       break;
492     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
493       return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
494       break;
495     case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
496       return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
497       break;
498     case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
499       return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
500       break;
501     case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
502       return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
503       break;
504     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
505       return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
506       break;
507     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
508       return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
509       break;
510     case TLS_ECDH_RSA_WITH_NULL_SHA:
511       return "TLS_ECDH_RSA_WITH_NULL_SHA";
512       break;
513     case TLS_ECDH_RSA_WITH_RC4_128_SHA:
514       return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
515       break;
516     case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
517       return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
518       break;
519     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
520       return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
521       break;
522     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
523       return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
524       break;
525     case TLS_ECDHE_RSA_WITH_NULL_SHA:
526       return "TLS_ECDHE_RSA_WITH_NULL_SHA";
527       break;
528     case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
529       return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
530       break;
531     case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
532       return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
533       break;
534     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
535       return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
536       break;
537     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
538       return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
539       break;
540     case TLS_ECDH_anon_WITH_NULL_SHA:
541       return "TLS_ECDH_anon_WITH_NULL_SHA";
542       break;
543     case TLS_ECDH_anon_WITH_RC4_128_SHA:
544       return "TLS_ECDH_anon_WITH_RC4_128_SHA";
545       break;
546     case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
547       return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
548       break;
549     case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
550       return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
551       break;
552     case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
553       return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
554       break;
555 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
556 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
557     /* TLS 1.2 (RFC 5246) */
558     case TLS_RSA_WITH_NULL_MD5:
559       return "TLS_RSA_WITH_NULL_MD5";
560       break;
561     case TLS_RSA_WITH_NULL_SHA:
562       return "TLS_RSA_WITH_NULL_SHA";
563       break;
564     case TLS_RSA_WITH_RC4_128_MD5:
565       return "TLS_RSA_WITH_RC4_128_MD5";
566       break;
567     case TLS_RSA_WITH_RC4_128_SHA:
568       return "TLS_RSA_WITH_RC4_128_SHA";
569       break;
570     case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
571       return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
572       break;
573     case TLS_RSA_WITH_NULL_SHA256:
574       return "TLS_RSA_WITH_NULL_SHA256";
575       break;
576     case TLS_RSA_WITH_AES_128_CBC_SHA256:
577       return "TLS_RSA_WITH_AES_128_CBC_SHA256";
578       break;
579     case TLS_RSA_WITH_AES_256_CBC_SHA256:
580       return "TLS_RSA_WITH_AES_256_CBC_SHA256";
581       break;
582     case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
583       return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
584       break;
585     case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
586       return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
587       break;
588     case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
589       return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
590       break;
591     case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
592       return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
593       break;
594     case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
595       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
596       break;
597     case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
598       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
599       break;
600     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
601       return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
602       break;
603     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
604       return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
605       break;
606     case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
607       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
608       break;
609     case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
610       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
611       break;
612     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
613       return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
614       break;
615     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
616       return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
617       break;
618     case TLS_DH_anon_WITH_RC4_128_MD5:
619       return "TLS_DH_anon_WITH_RC4_128_MD5";
620       break;
621     case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
622       return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
623       break;
624     case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
625       return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
626       break;
627     case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
628       return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
629       break;
630     /* TLS 1.2 with AES GCM (RFC 5288) */
631     case TLS_RSA_WITH_AES_128_GCM_SHA256:
632       return "TLS_RSA_WITH_AES_128_GCM_SHA256";
633       break;
634     case TLS_RSA_WITH_AES_256_GCM_SHA384:
635       return "TLS_RSA_WITH_AES_256_GCM_SHA384";
636       break;
637     case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
638       return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
639       break;
640     case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
641       return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
642       break;
643     case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
644       return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
645       break;
646     case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
647       return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
648       break;
649     case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
650       return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
651       break;
652     case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
653       return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
654       break;
655     case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
656       return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
657       break;
658     case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
659       return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
660       break;
661     case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
662       return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
663       break;
664     case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
665       return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
666       break;
667     /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
668     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
669       return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
670       break;
671     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
672       return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
673       break;
674     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
675       return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
676       break;
677     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
678       return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
679       break;
680     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
681       return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
682       break;
683     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
684       return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
685       break;
686     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
687       return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
688       break;
689     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
690       return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
691       break;
692     case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
693       return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
694       break;
695     case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
696       return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
697       break;
698     case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
699       return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
700       break;
701     case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
702       return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
703       break;
704     case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
705       return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
706       break;
707     case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
708       return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
709       break;
710     case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
711       return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
712       break;
713     case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
714       return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
715       break;
716     case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
717       return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
718       break;
719 #else
720     case SSL_RSA_WITH_NULL_MD5:
721       return "TLS_RSA_WITH_NULL_MD5";
722       break;
723     case SSL_RSA_WITH_NULL_SHA:
724       return "TLS_RSA_WITH_NULL_SHA";
725       break;
726     case SSL_RSA_WITH_RC4_128_MD5:
727       return "TLS_RSA_WITH_RC4_128_MD5";
728       break;
729     case SSL_RSA_WITH_RC4_128_SHA:
730       return "TLS_RSA_WITH_RC4_128_SHA";
731       break;
732     case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
733       return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
734       break;
735     case SSL_DH_anon_WITH_RC4_128_MD5:
736       return "TLS_DH_anon_WITH_RC4_128_MD5";
737       break;
738     case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
739       return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
740       break;
741 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
742 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
743     /* TLS PSK (RFC 4279): */
744     case TLS_PSK_WITH_RC4_128_SHA:
745       return "TLS_PSK_WITH_RC4_128_SHA";
746       break;
747     case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
748       return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
749       break;
750     case TLS_PSK_WITH_AES_128_CBC_SHA:
751       return "TLS_PSK_WITH_AES_128_CBC_SHA";
752       break;
753     case TLS_PSK_WITH_AES_256_CBC_SHA:
754       return "TLS_PSK_WITH_AES_256_CBC_SHA";
755       break;
756     case TLS_DHE_PSK_WITH_RC4_128_SHA:
757       return "TLS_DHE_PSK_WITH_RC4_128_SHA";
758       break;
759     case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
760       return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
761       break;
762     case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
763       return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
764       break;
765     case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
766       return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
767       break;
768     case TLS_RSA_PSK_WITH_RC4_128_SHA:
769       return "TLS_RSA_PSK_WITH_RC4_128_SHA";
770       break;
771     case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
772       return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
773       break;
774     case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
775       return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
776       break;
777     case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
778       return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
779       break;
780     /* More TLS PSK (RFC 4785): */
781     case TLS_PSK_WITH_NULL_SHA:
782       return "TLS_PSK_WITH_NULL_SHA";
783       break;
784     case TLS_DHE_PSK_WITH_NULL_SHA:
785       return "TLS_DHE_PSK_WITH_NULL_SHA";
786       break;
787     case TLS_RSA_PSK_WITH_NULL_SHA:
788       return "TLS_RSA_PSK_WITH_NULL_SHA";
789       break;
790     /* Even more TLS PSK (RFC 5487): */
791     case TLS_PSK_WITH_AES_128_GCM_SHA256:
792       return "TLS_PSK_WITH_AES_128_GCM_SHA256";
793       break;
794     case TLS_PSK_WITH_AES_256_GCM_SHA384:
795       return "TLS_PSK_WITH_AES_256_GCM_SHA384";
796       break;
797     case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
798       return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
799       break;
800     case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
801       return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
802       break;
803     case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
804       return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
805       break;
806     case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
807       return "TLS_PSK_WITH_AES_256_GCM_SHA384";
808       break;
809     case TLS_PSK_WITH_AES_128_CBC_SHA256:
810       return "TLS_PSK_WITH_AES_128_CBC_SHA256";
811       break;
812     case TLS_PSK_WITH_AES_256_CBC_SHA384:
813       return "TLS_PSK_WITH_AES_256_CBC_SHA384";
814       break;
815     case TLS_PSK_WITH_NULL_SHA256:
816       return "TLS_PSK_WITH_NULL_SHA256";
817       break;
818     case TLS_PSK_WITH_NULL_SHA384:
819       return "TLS_PSK_WITH_NULL_SHA384";
820       break;
821     case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
822       return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
823       break;
824     case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
825       return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
826       break;
827     case TLS_DHE_PSK_WITH_NULL_SHA256:
828       return "TLS_DHE_PSK_WITH_NULL_SHA256";
829       break;
830     case TLS_DHE_PSK_WITH_NULL_SHA384:
831       return "TLS_RSA_PSK_WITH_NULL_SHA384";
832       break;
833     case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
834       return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
835       break;
836     case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
837       return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
838       break;
839     case TLS_RSA_PSK_WITH_NULL_SHA256:
840       return "TLS_RSA_PSK_WITH_NULL_SHA256";
841       break;
842     case TLS_RSA_PSK_WITH_NULL_SHA384:
843       return "TLS_RSA_PSK_WITH_NULL_SHA384";
844       break;
845 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
846 #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
847     /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */
848     case TLS_AES_128_GCM_SHA256:
849       return "TLS_AES_128_GCM_SHA256";
850       break;
851     case TLS_AES_256_GCM_SHA384:
852       return "TLS_AES_256_GCM_SHA384";
853       break;
854     case TLS_CHACHA20_POLY1305_SHA256:
855       return "TLS_CHACHA20_POLY1305_SHA256";
856       break;
857     case TLS_AES_128_CCM_SHA256:
858       return "TLS_AES_128_CCM_SHA256";
859       break;
860     case TLS_AES_128_CCM_8_SHA256:
861       return "TLS_AES_128_CCM_8_SHA256";
862       break;
863     case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
864       return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
865       break;
866     case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
867       return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
868       break;
869 #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
870   }
871   return "TLS_NULL_WITH_NULL_NULL";
872 }
873 #endif /* !CURL_DISABLE_VERBOSE_STRINGS */
874 
875 #if CURL_BUILD_MAC
GetDarwinVersionNumber(int * major,int * minor)876 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
877 {
878   int mib[2];
879   char *os_version;
880   size_t os_version_len;
881   char *os_version_major, *os_version_minor;
882   char *tok_buf;
883 
884   /* Get the Darwin kernel version from the kernel using sysctl(): */
885   mib[0] = CTL_KERN;
886   mib[1] = KERN_OSRELEASE;
887   if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
888     return;
889   os_version = malloc(os_version_len*sizeof(char));
890   if(!os_version)
891     return;
892   if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
893     free(os_version);
894     return;
895   }
896 
897   /* Parse the version: */
898   os_version_major = strtok_r(os_version, ".", &tok_buf);
899   os_version_minor = strtok_r(NULL, ".", &tok_buf);
900   *major = atoi(os_version_major);
901   *minor = atoi(os_version_minor);
902   free(os_version);
903 }
904 #endif /* CURL_BUILD_MAC */
905 
906 /* Apple provides a myriad of ways of getting information about a certificate
907    into a string. Some aren't available under iOS or newer cats. So here's
908    a unified function for getting a string describing the certificate that
909    ought to work in all cats starting with Leopard. */
getsubject(SecCertificateRef cert)910 CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
911 {
912   CFStringRef server_cert_summary = CFSTR("(null)");
913 
914 #if CURL_BUILD_IOS
915   /* iOS: There's only one way to do this. */
916   server_cert_summary = SecCertificateCopySubjectSummary(cert);
917 #else
918 #if CURL_BUILD_MAC_10_7
919   /* Lion & later: Get the long description if we can. */
920   if(SecCertificateCopyLongDescription != NULL)
921     server_cert_summary =
922       SecCertificateCopyLongDescription(NULL, cert, NULL);
923   else
924 #endif /* CURL_BUILD_MAC_10_7 */
925 #if CURL_BUILD_MAC_10_6
926   /* Snow Leopard: Get the certificate summary. */
927   if(SecCertificateCopySubjectSummary != NULL)
928     server_cert_summary = SecCertificateCopySubjectSummary(cert);
929   else
930 #endif /* CURL_BUILD_MAC_10_6 */
931   /* Leopard is as far back as we go... */
932   (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
933 #endif /* CURL_BUILD_IOS */
934   return server_cert_summary;
935 }
936 
CopyCertSubject(struct Curl_easy * data,SecCertificateRef cert,char ** certp)937 static CURLcode CopyCertSubject(struct Curl_easy *data,
938                                 SecCertificateRef cert, char **certp)
939 {
940   CFStringRef c = getsubject(cert);
941   CURLcode result = CURLE_OK;
942   const char *direct;
943   char *cbuf = NULL;
944   *certp = NULL;
945 
946   if(!c) {
947     failf(data, "SSL: invalid CA certificate subject");
948     return CURLE_OUT_OF_MEMORY;
949   }
950 
951   /* If the subject is already available as UTF-8 encoded (ie 'direct') then
952      use that, else convert it. */
953   direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8);
954   if(direct) {
955     *certp = strdup(direct);
956     if(!*certp) {
957       failf(data, "SSL: out of memory");
958       result = CURLE_OUT_OF_MEMORY;
959     }
960   }
961   else {
962     size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1;
963     cbuf = calloc(cbuf_size, 1);
964     if(cbuf) {
965       if(!CFStringGetCString(c, cbuf, cbuf_size,
966                              kCFStringEncodingUTF8)) {
967         failf(data, "SSL: invalid CA certificate subject");
968         result = CURLE_SSL_CACERT;
969       }
970       else
971         /* pass back the buffer */
972         *certp = cbuf;
973     }
974     else {
975       failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size);
976       result = CURLE_OUT_OF_MEMORY;
977     }
978   }
979   if(result)
980     free(cbuf);
981   CFRelease(c);
982   return result;
983 }
984 
985 #if CURL_SUPPORT_MAC_10_6
986 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
987    deprecation warnings, so let's not compile this unless it's necessary: */
CopyIdentityWithLabelOldSchool(char * label,SecIdentityRef * out_c_a_k)988 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
989                                                SecIdentityRef *out_c_a_k)
990 {
991   OSStatus status = errSecItemNotFound;
992   SecKeychainAttributeList attr_list;
993   SecKeychainAttribute attr;
994   SecKeychainSearchRef search = NULL;
995   SecCertificateRef cert = NULL;
996 
997   /* Set up the attribute list: */
998   attr_list.count = 1L;
999   attr_list.attr = &attr;
1000 
1001   /* Set up our lone search criterion: */
1002   attr.tag = kSecLabelItemAttr;
1003   attr.data = label;
1004   attr.length = (UInt32)strlen(label);
1005 
1006   /* Start searching: */
1007   status = SecKeychainSearchCreateFromAttributes(NULL,
1008                                                  kSecCertificateItemClass,
1009                                                  &attr_list,
1010                                                  &search);
1011   if(status == noErr) {
1012     status = SecKeychainSearchCopyNext(search,
1013                                        (SecKeychainItemRef *)&cert);
1014     if(status == noErr && cert) {
1015       /* If we found a certificate, does it have a private key? */
1016       status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
1017       CFRelease(cert);
1018     }
1019   }
1020 
1021   if(search)
1022     CFRelease(search);
1023   return status;
1024 }
1025 #endif /* CURL_SUPPORT_MAC_10_6 */
1026 
CopyIdentityWithLabel(char * label,SecIdentityRef * out_cert_and_key)1027 static OSStatus CopyIdentityWithLabel(char *label,
1028                                       SecIdentityRef *out_cert_and_key)
1029 {
1030   OSStatus status = errSecItemNotFound;
1031 
1032 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1033   CFArrayRef keys_list;
1034   CFIndex keys_list_count;
1035   CFIndex i;
1036   CFStringRef common_name;
1037 
1038   /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
1039      kSecClassIdentity was introduced in Lion. If both exist, let's use them
1040      to find the certificate. */
1041   if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
1042     CFTypeRef keys[5];
1043     CFTypeRef values[5];
1044     CFDictionaryRef query_dict;
1045     CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
1046       kCFStringEncodingUTF8);
1047 
1048     /* Set up our search criteria and expected results: */
1049     values[0] = kSecClassIdentity; /* we want a certificate and a key */
1050     keys[0] = kSecClass;
1051     values[1] = kCFBooleanTrue;    /* we want a reference */
1052     keys[1] = kSecReturnRef;
1053     values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the
1054                                     * label matching below worked correctly */
1055     keys[2] = kSecMatchLimit;
1056     /* identity searches need a SecPolicyRef in order to work */
1057     values[3] = SecPolicyCreateSSL(false, NULL);
1058     keys[3] = kSecMatchPolicy;
1059     /* match the name of the certificate (doesn't work in macOS 10.12.1) */
1060     values[4] = label_cf;
1061     keys[4] = kSecAttrLabel;
1062     query_dict = CFDictionaryCreate(NULL, (const void **)keys,
1063                                     (const void **)values, 5L,
1064                                     &kCFCopyStringDictionaryKeyCallBacks,
1065                                     &kCFTypeDictionaryValueCallBacks);
1066     CFRelease(values[3]);
1067 
1068     /* Do we have a match? */
1069     status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
1070 
1071     /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity,
1072      * we need to find the correct identity ourselves */
1073     if(status == noErr) {
1074       keys_list_count = CFArrayGetCount(keys_list);
1075       *out_cert_and_key = NULL;
1076       status = 1;
1077       for(i = 0; i<keys_list_count; i++) {
1078         OSStatus err = noErr;
1079         SecCertificateRef cert = NULL;
1080         SecIdentityRef identity =
1081           (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
1082         err = SecIdentityCopyCertificate(identity, &cert);
1083         if(err == noErr) {
1084 #if CURL_BUILD_IOS
1085           common_name = SecCertificateCopySubjectSummary(cert);
1086 #elif CURL_BUILD_MAC_10_7
1087           SecCertificateCopyCommonName(cert, &common_name);
1088 #endif
1089           if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
1090             CFRelease(cert);
1091             CFRelease(common_name);
1092             CFRetain(identity);
1093             *out_cert_and_key = identity;
1094             status = noErr;
1095             break;
1096           }
1097           CFRelease(common_name);
1098         }
1099         CFRelease(cert);
1100       }
1101     }
1102 
1103     if(keys_list)
1104       CFRelease(keys_list);
1105     CFRelease(query_dict);
1106     CFRelease(label_cf);
1107   }
1108   else {
1109 #if CURL_SUPPORT_MAC_10_6
1110     /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
1111     status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1112 #endif /* CURL_SUPPORT_MAC_10_6 */
1113   }
1114 #elif CURL_SUPPORT_MAC_10_6
1115   /* For developers building on older cats, we have no choice but to fall back
1116      to SecKeychainSearch. */
1117   status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1118 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1119   return status;
1120 }
1121 
CopyIdentityFromPKCS12File(const char * cPath,const char * cPassword,SecIdentityRef * out_cert_and_key)1122 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
1123                                            const char *cPassword,
1124                                            SecIdentityRef *out_cert_and_key)
1125 {
1126   OSStatus status = errSecItemNotFound;
1127   CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
1128     (const UInt8 *)cPath, strlen(cPath), false);
1129   CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
1130     cPassword, kCFStringEncodingUTF8) : NULL;
1131   CFDataRef pkcs_data = NULL;
1132 
1133   /* We can import P12 files on iOS or OS X 10.7 or later: */
1134   /* These constants are documented as having first appeared in 10.6 but they
1135      raise linker errors when used on that cat for some reason. */
1136 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1137   if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
1138     NULL, NULL, &status)) {
1139     const void *cKeys[] = {kSecImportExportPassphrase};
1140     const void *cValues[] = {password};
1141     CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
1142       password ? 1L : 0L, NULL, NULL);
1143     CFArrayRef items = NULL;
1144 
1145     /* Here we go: */
1146     status = SecPKCS12Import(pkcs_data, options, &items);
1147     if(status == errSecSuccess && items && CFArrayGetCount(items)) {
1148       CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
1149       const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
1150         kSecImportItemIdentity);
1151 
1152       /* Retain the identity; we don't care about any other data... */
1153       CFRetain(temp_identity);
1154       *out_cert_and_key = (SecIdentityRef)temp_identity;
1155     }
1156 
1157     if(items)
1158       CFRelease(items);
1159     CFRelease(options);
1160     CFRelease(pkcs_data);
1161   }
1162 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1163   if(password)
1164     CFRelease(password);
1165   CFRelease(pkcs_url);
1166   return status;
1167 }
1168 
1169 /* This code was borrowed from nss.c, with some modifications:
1170  * Determine whether the nickname passed in is a filename that needs to
1171  * be loaded as a PEM or a regular NSS nickname.
1172  *
1173  * returns 1 for a file
1174  * returns 0 for not a file
1175  */
is_file(const char * filename)1176 CF_INLINE bool is_file(const char *filename)
1177 {
1178   struct_stat st;
1179 
1180   if(filename == NULL)
1181     return false;
1182 
1183   if(stat(filename, &st) == 0)
1184     return S_ISREG(st.st_mode);
1185   return false;
1186 }
1187 
1188 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
darwinssl_version_from_curl(SSLProtocol * darwinver,long ssl_version)1189 static CURLcode darwinssl_version_from_curl(SSLProtocol *darwinver,
1190                                             long ssl_version)
1191 {
1192   switch(ssl_version) {
1193     case CURL_SSLVERSION_TLSv1_0:
1194       *darwinver = kTLSProtocol1;
1195       return CURLE_OK;
1196     case CURL_SSLVERSION_TLSv1_1:
1197       *darwinver = kTLSProtocol11;
1198       return CURLE_OK;
1199     case CURL_SSLVERSION_TLSv1_2:
1200       *darwinver = kTLSProtocol12;
1201       return CURLE_OK;
1202     case CURL_SSLVERSION_TLSv1_3:
1203       /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */
1204 #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
1205       /* We can assume __builtin_available() will always work in the
1206          10.13/11.0 SDK: */
1207       if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1208         *darwinver = kTLSProtocol13;
1209         return CURLE_OK;
1210       }
1211 #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
1212       break;
1213   }
1214   return CURLE_SSL_CONNECT_ERROR;
1215 }
1216 #endif
1217 
1218 static CURLcode
set_ssl_version_min_max(struct connectdata * conn,int sockindex)1219 set_ssl_version_min_max(struct connectdata *conn, int sockindex)
1220 {
1221   struct Curl_easy *data = conn->data;
1222   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1223   long ssl_version = SSL_CONN_CONFIG(version);
1224   long ssl_version_max = SSL_CONN_CONFIG(version_max);
1225   long max_supported_version_by_os;
1226 
1227   /* macOS 10.5-10.7 supported TLS 1.0 only.
1228      macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
1229      macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
1230 #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
1231   if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1232     max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3;
1233   }
1234   else {
1235     max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1236   }
1237 #else
1238   max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1239 #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
1240 
1241   switch(ssl_version) {
1242     case CURL_SSLVERSION_DEFAULT:
1243     case CURL_SSLVERSION_TLSv1:
1244       ssl_version = CURL_SSLVERSION_TLSv1_0;
1245       ssl_version_max = max_supported_version_by_os;
1246       break;
1247   }
1248 
1249   switch(ssl_version_max) {
1250     case CURL_SSLVERSION_MAX_NONE:
1251       ssl_version_max = ssl_version << 16;
1252       break;
1253     case CURL_SSLVERSION_MAX_DEFAULT:
1254       ssl_version_max = max_supported_version_by_os;
1255       break;
1256   }
1257 
1258 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1259   if(SSLSetProtocolVersionMax != NULL) {
1260     SSLProtocol darwin_ver_min = kTLSProtocol1;
1261     SSLProtocol darwin_ver_max = kTLSProtocol1;
1262     CURLcode result = darwinssl_version_from_curl(&darwin_ver_min,
1263                                                   ssl_version);
1264     if(result) {
1265       failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
1266       return result;
1267     }
1268     result = darwinssl_version_from_curl(&darwin_ver_max,
1269                                          ssl_version_max >> 16);
1270     if(result) {
1271       failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
1272       return result;
1273     }
1274 
1275     (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, darwin_ver_min);
1276     (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, darwin_ver_max);
1277     return result;
1278   }
1279   else {
1280 #if CURL_SUPPORT_MAC_10_8
1281     long i = ssl_version;
1282     (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1283                                        kSSLProtocolAll,
1284                                        false);
1285     for(; i <= (ssl_version_max >> 16); i++) {
1286       switch(i) {
1287         case CURL_SSLVERSION_TLSv1_0:
1288           (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1289                                             kTLSProtocol1,
1290                                             true);
1291           break;
1292         case CURL_SSLVERSION_TLSv1_1:
1293           (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1294                                             kTLSProtocol11,
1295                                             true);
1296           break;
1297         case CURL_SSLVERSION_TLSv1_2:
1298           (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1299                                             kTLSProtocol12,
1300                                             true);
1301           break;
1302         case CURL_SSLVERSION_TLSv1_3:
1303           failf(data, "Your version of the OS does not support TLSv1.3");
1304           return CURLE_SSL_CONNECT_ERROR;
1305       }
1306     }
1307     return CURLE_OK;
1308 #endif  /* CURL_SUPPORT_MAC_10_8 */
1309   }
1310 #endif  /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1311   failf(data, "DarwinSSL: cannot set SSL protocol");
1312   return CURLE_SSL_CONNECT_ERROR;
1313 }
1314 
1315 
darwinssl_connect_step1(struct connectdata * conn,int sockindex)1316 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
1317                                         int sockindex)
1318 {
1319   struct Curl_easy *data = conn->data;
1320   curl_socket_t sockfd = conn->sock[sockindex];
1321   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1322   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
1323   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
1324   char * const ssl_cert = SSL_SET_OPTION(cert);
1325   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
1326     conn->host.name;
1327   const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
1328 #ifdef ENABLE_IPV6
1329   struct in6_addr addr;
1330 #else
1331   struct in_addr addr;
1332 #endif /* ENABLE_IPV6 */
1333   size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1334   SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1335   OSStatus err = noErr;
1336 #if CURL_BUILD_MAC
1337   int darwinver_maj = 0, darwinver_min = 0;
1338 
1339   GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1340 #endif /* CURL_BUILD_MAC */
1341 
1342 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1343   if(SSLCreateContext != NULL) {  /* use the newer API if avaialble */
1344     if(BACKEND->ssl_ctx)
1345       CFRelease(BACKEND->ssl_ctx);
1346     BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1347     if(!BACKEND->ssl_ctx) {
1348       failf(data, "SSL: couldn't create a context!");
1349       return CURLE_OUT_OF_MEMORY;
1350     }
1351   }
1352   else {
1353   /* The old ST API does not exist under iOS, so don't compile it: */
1354 #if CURL_SUPPORT_MAC_10_8
1355     if(BACKEND->ssl_ctx)
1356       (void)SSLDisposeContext(BACKEND->ssl_ctx);
1357     err = SSLNewContext(false, &(BACKEND->ssl_ctx));
1358     if(err != noErr) {
1359       failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1360       return CURLE_OUT_OF_MEMORY;
1361     }
1362 #endif /* CURL_SUPPORT_MAC_10_8 */
1363   }
1364 #else
1365   if(BACKEND->ssl_ctx)
1366     (void)SSLDisposeContext(BACKEND->ssl_ctx);
1367   err = SSLNewContext(false, &(BACKEND->ssl_ctx));
1368   if(err != noErr) {
1369     failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1370     return CURLE_OUT_OF_MEMORY;
1371   }
1372 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1373   BACKEND->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1374 
1375   /* check to see if we've been told to use an explicit SSL/TLS version */
1376 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1377   if(SSLSetProtocolVersionMax != NULL) {
1378     switch(conn->ssl_config.version) {
1379     case CURL_SSLVERSION_DEFAULT:
1380     case CURL_SSLVERSION_TLSv1:
1381       (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
1382 #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
1383       if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1384         (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol13);
1385       }
1386       else {
1387         (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
1388       }
1389 #else
1390       (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
1391 #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
1392       break;
1393     case CURL_SSLVERSION_TLSv1_0:
1394     case CURL_SSLVERSION_TLSv1_1:
1395     case CURL_SSLVERSION_TLSv1_2:
1396     case CURL_SSLVERSION_TLSv1_3:
1397       {
1398         CURLcode result = set_ssl_version_min_max(conn, sockindex);
1399         if(result != CURLE_OK)
1400           return result;
1401         break;
1402       }
1403     case CURL_SSLVERSION_SSLv3:
1404       err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol3);
1405       if(err != noErr) {
1406         failf(data, "Your version of the OS does not support SSLv3");
1407         return CURLE_SSL_CONNECT_ERROR;
1408       }
1409       (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol3);
1410       break;
1411     case CURL_SSLVERSION_SSLv2:
1412       err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol2);
1413       if(err != noErr) {
1414         failf(data, "Your version of the OS does not support SSLv2");
1415         return CURLE_SSL_CONNECT_ERROR;
1416       }
1417       (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol2);
1418       break;
1419     default:
1420       failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1421       return CURLE_SSL_CONNECT_ERROR;
1422     }
1423   }
1424   else {
1425 #if CURL_SUPPORT_MAC_10_8
1426     (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1427                                        kSSLProtocolAll,
1428                                        false);
1429     switch(conn->ssl_config.version) {
1430     case CURL_SSLVERSION_DEFAULT:
1431     case CURL_SSLVERSION_TLSv1:
1432       (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1433                                          kTLSProtocol1,
1434                                          true);
1435       (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1436                                          kTLSProtocol11,
1437                                          true);
1438       (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1439                                          kTLSProtocol12,
1440                                          true);
1441       break;
1442     case CURL_SSLVERSION_TLSv1_0:
1443     case CURL_SSLVERSION_TLSv1_1:
1444     case CURL_SSLVERSION_TLSv1_2:
1445     case CURL_SSLVERSION_TLSv1_3:
1446       {
1447         CURLcode result = set_ssl_version_min_max(conn, sockindex);
1448         if(result != CURLE_OK)
1449           return result;
1450         break;
1451       }
1452     case CURL_SSLVERSION_SSLv3:
1453       err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1454                                          kSSLProtocol3,
1455                                          true);
1456       if(err != noErr) {
1457         failf(data, "Your version of the OS does not support SSLv3");
1458         return CURLE_SSL_CONNECT_ERROR;
1459       }
1460       break;
1461     case CURL_SSLVERSION_SSLv2:
1462       err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1463                                          kSSLProtocol2,
1464                                          true);
1465       if(err != noErr) {
1466         failf(data, "Your version of the OS does not support SSLv2");
1467         return CURLE_SSL_CONNECT_ERROR;
1468       }
1469       break;
1470     default:
1471       failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1472       return CURLE_SSL_CONNECT_ERROR;
1473     }
1474 #endif  /* CURL_SUPPORT_MAC_10_8 */
1475   }
1476 #else
1477   if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
1478     failf(data, "Your version of the OS does not support to set maximum"
1479                 " SSL/TLS version");
1480     return CURLE_SSL_CONNECT_ERROR;
1481   }
1482   (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, kSSLProtocolAll, false);
1483   switch(conn->ssl_config.version) {
1484   case CURL_SSLVERSION_DEFAULT:
1485   case CURL_SSLVERSION_TLSv1:
1486   case CURL_SSLVERSION_TLSv1_0:
1487     (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1488                                        kTLSProtocol1,
1489                                        true);
1490     break;
1491   case CURL_SSLVERSION_TLSv1_1:
1492     failf(data, "Your version of the OS does not support TLSv1.1");
1493     return CURLE_SSL_CONNECT_ERROR;
1494   case CURL_SSLVERSION_TLSv1_2:
1495     failf(data, "Your version of the OS does not support TLSv1.2");
1496     return CURLE_SSL_CONNECT_ERROR;
1497   case CURL_SSLVERSION_TLSv1_3:
1498     failf(data, "Your version of the OS does not support TLSv1.3");
1499     return CURLE_SSL_CONNECT_ERROR;
1500   case CURL_SSLVERSION_SSLv2:
1501     err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1502                                        kSSLProtocol2,
1503                                        true);
1504     if(err != noErr) {
1505       failf(data, "Your version of the OS does not support SSLv2");
1506       return CURLE_SSL_CONNECT_ERROR;
1507     }
1508     break;
1509   case CURL_SSLVERSION_SSLv3:
1510     err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1511                                        kSSLProtocol3,
1512                                        true);
1513     if(err != noErr) {
1514       failf(data, "Your version of the OS does not support SSLv3");
1515       return CURLE_SSL_CONNECT_ERROR;
1516     }
1517     break;
1518   default:
1519     failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1520     return CURLE_SSL_CONNECT_ERROR;
1521   }
1522 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1523 
1524   if(SSL_SET_OPTION(key)) {
1525     infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1526           "Transport. The private key must be in the Keychain.\n");
1527   }
1528 
1529   if(ssl_cert) {
1530     SecIdentityRef cert_and_key = NULL;
1531     bool is_cert_file = is_file(ssl_cert);
1532 
1533     /* User wants to authenticate with a client cert. Look for it:
1534        If we detect that this is a file on disk, then let's load it.
1535        Otherwise, assume that the user wants to use an identity loaded
1536        from the Keychain. */
1537     if(is_cert_file) {
1538       if(!SSL_SET_OPTION(cert_type))
1539         infof(data, "WARNING: SSL: Certificate type not set, assuming "
1540                     "PKCS#12 format.\n");
1541       else if(strncmp(SSL_SET_OPTION(cert_type), "P12",
1542         strlen(SSL_SET_OPTION(cert_type))) != 0)
1543         infof(data, "WARNING: SSL: The Security framework only supports "
1544                     "loading identities that are in PKCS#12 format.\n");
1545 
1546       err = CopyIdentityFromPKCS12File(ssl_cert,
1547         SSL_SET_OPTION(key_passwd), &cert_and_key);
1548     }
1549     else
1550       err = CopyIdentityWithLabel(ssl_cert, &cert_and_key);
1551 
1552     if(err == noErr && cert_and_key) {
1553       SecCertificateRef cert = NULL;
1554       CFTypeRef certs_c[1];
1555       CFArrayRef certs;
1556 
1557       /* If we found one, print it out: */
1558       err = SecIdentityCopyCertificate(cert_and_key, &cert);
1559       if(err == noErr) {
1560         char *certp;
1561         CURLcode result = CopyCertSubject(data, cert, &certp);
1562         if(!result) {
1563           infof(data, "Client certificate: %s\n", certp);
1564           free(certp);
1565         }
1566 
1567         CFRelease(cert);
1568         if(result)
1569           return result;
1570       }
1571       certs_c[0] = cert_and_key;
1572       certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1573                             &kCFTypeArrayCallBacks);
1574       err = SSLSetCertificate(BACKEND->ssl_ctx, certs);
1575       if(certs)
1576         CFRelease(certs);
1577       if(err != noErr) {
1578         failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1579         return CURLE_SSL_CERTPROBLEM;
1580       }
1581       CFRelease(cert_and_key);
1582     }
1583     else {
1584       switch(err) {
1585       case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1586         failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1587                     "and its private key.", ssl_cert);
1588         break;
1589       case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1590         failf(data, "SSL: Couldn't make sense of the data in the "
1591                     "certificate \"%s\" and its private key.",
1592                     ssl_cert);
1593         break;
1594       case -25260: /* errSecPassphraseRequired */
1595         failf(data, "SSL The certificate \"%s\" requires a password.",
1596                     ssl_cert);
1597         break;
1598       case errSecItemNotFound:
1599         failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1600                     "key in the Keychain.", ssl_cert);
1601         break;
1602       default:
1603         failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1604                     "key: OSStatus %d", ssl_cert, err);
1605         break;
1606       }
1607       return CURLE_SSL_CERTPROBLEM;
1608     }
1609   }
1610 
1611   /* SSL always tries to verify the peer, this only says whether it should
1612    * fail to connect if the verification fails, or if it should continue
1613    * anyway. In the latter case the result of the verification is checked with
1614    * SSL_get_verify_result() below. */
1615 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1616   /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1617      a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1618      works, it doesn't work as expected under Snow Leopard, Lion or
1619      Mountain Lion.
1620      So we need to call SSLSetEnableCertVerify() on those older cats in order
1621      to disable certificate validation if the user turned that off.
1622      (SecureTransport will always validate the certificate chain by
1623      default.)
1624   Note:
1625   Darwin 11.x.x is Lion (10.7)
1626   Darwin 12.x.x is Mountain Lion (10.8)
1627   Darwin 13.x.x is Mavericks (10.9)
1628   Darwin 14.x.x is Yosemite (10.10)
1629   Darwin 15.x.x is El Capitan (10.11)
1630   */
1631 #if CURL_BUILD_MAC
1632   if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
1633 #else
1634   if(SSLSetSessionOption != NULL) {
1635 #endif /* CURL_BUILD_MAC */
1636     bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
1637     err = SSLSetSessionOption(BACKEND->ssl_ctx,
1638                               kSSLSessionOptionBreakOnServerAuth,
1639                               break_on_auth);
1640     if(err != noErr) {
1641       failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1642       return CURLE_SSL_CONNECT_ERROR;
1643     }
1644   }
1645   else {
1646 #if CURL_SUPPORT_MAC_10_8
1647     err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
1648                                  conn->ssl_config.verifypeer?true:false);
1649     if(err != noErr) {
1650       failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1651       return CURLE_SSL_CONNECT_ERROR;
1652     }
1653 #endif /* CURL_SUPPORT_MAC_10_8 */
1654   }
1655 #else
1656   err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
1657                                conn->ssl_config.verifypeer?true:false);
1658   if(err != noErr) {
1659     failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1660     return CURLE_SSL_CONNECT_ERROR;
1661   }
1662 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1663 
1664   if(ssl_cafile && verifypeer) {
1665     bool is_cert_file = is_file(ssl_cafile);
1666 
1667     if(!is_cert_file) {
1668       failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
1669       return CURLE_SSL_CACERT_BADFILE;
1670     }
1671   }
1672 
1673   /* Configure hostname check. SNI is used if available.
1674    * Both hostname check and SNI require SSLSetPeerDomainName().
1675    * Also: the verifyhost setting influences SNI usage */
1676   if(conn->ssl_config.verifyhost) {
1677     err = SSLSetPeerDomainName(BACKEND->ssl_ctx, hostname,
1678     strlen(hostname));
1679 
1680     if(err != noErr) {
1681       infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1682             err);
1683     }
1684 
1685     if((Curl_inet_pton(AF_INET, hostname, &addr))
1686   #ifdef ENABLE_IPV6
1687     || (Curl_inet_pton(AF_INET6, hostname, &addr))
1688   #endif
1689        ) {
1690       infof(data, "WARNING: using IP address, SNI is being disabled by "
1691             "the OS.\n");
1692     }
1693   }
1694   else {
1695     infof(data, "WARNING: disabling hostname validation also disables SNI.\n");
1696   }
1697 
1698   /* Disable cipher suites that ST supports but are not safe. These ciphers
1699      are unlikely to be used in any case since ST gives other ciphers a much
1700      higher priority, but it's probably better that we not connect at all than
1701      to give the user a false sense of security if the server only supports
1702      insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1703   (void)SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count);
1704   all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1705   allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1706   if(all_ciphers && allowed_ciphers &&
1707      SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers,
1708        &all_ciphers_count) == noErr) {
1709     for(i = 0UL ; i < all_ciphers_count ; i++) {
1710 #if CURL_BUILD_MAC
1711      /* There's a known bug in early versions of Mountain Lion where ST's ECC
1712         ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1713         Work around the problem here by disabling those ciphers if we are
1714         running in an affected version of OS X. */
1715       if(darwinver_maj == 12 && darwinver_min <= 3 &&
1716          all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1717         continue;
1718       }
1719 #endif /* CURL_BUILD_MAC */
1720       switch(all_ciphers[i]) {
1721         /* Disable NULL ciphersuites: */
1722         case SSL_NULL_WITH_NULL_NULL:
1723         case SSL_RSA_WITH_NULL_MD5:
1724         case SSL_RSA_WITH_NULL_SHA:
1725         case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1726         case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1727         case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1728         case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1729         case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1730         case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1731         case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1732         case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1733         case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1734         case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1735         case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1736         case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1737         case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1738         case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1739         case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1740         /* Disable anonymous ciphersuites: */
1741         case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1742         case SSL_DH_anon_WITH_RC4_128_MD5:
1743         case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1744         case SSL_DH_anon_WITH_DES_CBC_SHA:
1745         case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1746         case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1747         case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1748         case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1749         case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1750         case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1751         case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1752         case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1753         case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1754         case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1755         case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1756         case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1757         /* Disable weak key ciphersuites: */
1758         case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1759         case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1760         case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1761         case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1762         case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1763         case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1764         case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1765         case SSL_RSA_WITH_DES_CBC_SHA:
1766         case SSL_DH_DSS_WITH_DES_CBC_SHA:
1767         case SSL_DH_RSA_WITH_DES_CBC_SHA:
1768         case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1769         case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1770         /* Disable IDEA: */
1771         case SSL_RSA_WITH_IDEA_CBC_SHA:
1772         case SSL_RSA_WITH_IDEA_CBC_MD5:
1773         /* Disable RC4: */
1774         case SSL_RSA_WITH_RC4_128_MD5:
1775         case SSL_RSA_WITH_RC4_128_SHA:
1776         case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
1777         case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/
1778         case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
1779         case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
1780         case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */
1781         case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */
1782         case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */
1783           break;
1784         default: /* enable everything else */
1785           allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1786           break;
1787       }
1788     }
1789     err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers,
1790                                allowed_ciphers_count);
1791     if(err != noErr) {
1792       failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1793       return CURLE_SSL_CONNECT_ERROR;
1794     }
1795   }
1796   else {
1797     Curl_safefree(all_ciphers);
1798     Curl_safefree(allowed_ciphers);
1799     failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1800     return CURLE_OUT_OF_MEMORY;
1801   }
1802   Curl_safefree(all_ciphers);
1803   Curl_safefree(allowed_ciphers);
1804 
1805 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1806   /* We want to enable 1/n-1 when using a CBC cipher unless the user
1807      specifically doesn't want us doing that: */
1808   if(SSLSetSessionOption != NULL) {
1809     /* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */
1810     SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1811                       !data->set.ssl.enable_beast);
1812     SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart,
1813                       data->set.ssl.falsestart); /* false start support */
1814   }
1815 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1816 
1817   /* Check if there's a cached ID we can/should use here! */
1818   if(SSL_SET_OPTION(primary.sessionid)) {
1819     char *ssl_sessionid;
1820     size_t ssl_sessionid_len;
1821 
1822     Curl_ssl_sessionid_lock(conn);
1823     if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1824                               &ssl_sessionid_len, sockindex)) {
1825       /* we got a session id, use it! */
1826       err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1827       Curl_ssl_sessionid_unlock(conn);
1828       if(err != noErr) {
1829         failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1830         return CURLE_SSL_CONNECT_ERROR;
1831       }
1832       /* Informational message */
1833       infof(data, "SSL re-using session ID\n");
1834     }
1835     /* If there isn't one, then let's make one up! This has to be done prior
1836        to starting the handshake. */
1837     else {
1838       CURLcode result;
1839       ssl_sessionid =
1840         aprintf("%s:%d:%d:%s:%hu", ssl_cafile,
1841                 verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
1842       ssl_sessionid_len = strlen(ssl_sessionid);
1843 
1844       err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1845       if(err != noErr) {
1846         Curl_ssl_sessionid_unlock(conn);
1847         failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1848         return CURLE_SSL_CONNECT_ERROR;
1849       }
1850 
1851       result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len,
1852                                      sockindex);
1853       Curl_ssl_sessionid_unlock(conn);
1854       if(result) {
1855         failf(data, "failed to store ssl session");
1856         return result;
1857       }
1858     }
1859   }
1860 
1861   err = SSLSetIOFuncs(BACKEND->ssl_ctx, SocketRead, SocketWrite);
1862   if(err != noErr) {
1863     failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1864     return CURLE_SSL_CONNECT_ERROR;
1865   }
1866 
1867   /* pass the raw socket into the SSL layers */
1868   /* We need to store the FD in a constant memory address, because
1869    * SSLSetConnection() will not copy that address. I've found that
1870    * conn->sock[sockindex] may change on its own. */
1871   BACKEND->ssl_sockfd = sockfd;
1872   err = SSLSetConnection(BACKEND->ssl_ctx, connssl);
1873   if(err != noErr) {
1874     failf(data, "SSL: SSLSetConnection() failed: %d", err);
1875     return CURLE_SSL_CONNECT_ERROR;
1876   }
1877 
1878   connssl->connecting_state = ssl_connect_2;
1879   return CURLE_OK;
1880 }
1881 
1882 static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
1883 {
1884   char *sep_start, *sep_end, *cert_start, *cert_end;
1885   size_t i, j, err;
1886   size_t len;
1887   unsigned char *b64;
1888 
1889   /* Jump through the separators at the beginning of the certificate. */
1890   sep_start = strstr(in, "-----");
1891   if(sep_start == NULL)
1892     return 0;
1893   cert_start = strstr(sep_start + 1, "-----");
1894   if(cert_start == NULL)
1895     return -1;
1896 
1897   cert_start += 5;
1898 
1899   /* Find separator after the end of the certificate. */
1900   cert_end = strstr(cert_start, "-----");
1901   if(cert_end == NULL)
1902     return -1;
1903 
1904   sep_end = strstr(cert_end + 1, "-----");
1905   if(sep_end == NULL)
1906     return -1;
1907   sep_end += 5;
1908 
1909   len = cert_end - cert_start;
1910   b64 = malloc(len + 1);
1911   if(!b64)
1912     return -1;
1913 
1914   /* Create base64 string without linefeeds. */
1915   for(i = 0, j = 0; i < len; i++) {
1916     if(cert_start[i] != '\r' && cert_start[i] != '\n')
1917       b64[j++] = cert_start[i];
1918   }
1919   b64[j] = '\0';
1920 
1921   err = Curl_base64_decode((const char *)b64, out, outlen);
1922   free(b64);
1923   if(err) {
1924     free(*out);
1925     return -1;
1926   }
1927 
1928   return sep_end - in;
1929 }
1930 
1931 static int read_cert(const char *file, unsigned char **out, size_t *outlen)
1932 {
1933   int fd;
1934   ssize_t n, len = 0, cap = 512;
1935   unsigned char buf[512], *data;
1936 
1937   fd = open(file, 0);
1938   if(fd < 0)
1939     return -1;
1940 
1941   data = malloc(cap);
1942   if(!data) {
1943     close(fd);
1944     return -1;
1945   }
1946 
1947   for(;;) {
1948     n = read(fd, buf, sizeof(buf));
1949     if(n < 0) {
1950       close(fd);
1951       free(data);
1952       return -1;
1953     }
1954     else if(n == 0) {
1955       close(fd);
1956       break;
1957     }
1958 
1959     if(len + n >= cap) {
1960       cap *= 2;
1961       data = realloc(data, cap);
1962       if(!data) {
1963         close(fd);
1964         return -1;
1965       }
1966     }
1967 
1968     memcpy(data + len, buf, n);
1969     len += n;
1970   }
1971   data[len] = '\0';
1972 
1973   *out = data;
1974   *outlen = len;
1975 
1976   return 0;
1977 }
1978 
1979 static int sslerr_to_curlerr(struct Curl_easy *data, int err)
1980 {
1981   switch(err) {
1982     case errSSLXCertChainInvalid:
1983       failf(data, "SSL certificate problem: Invalid certificate chain");
1984       return CURLE_SSL_CACERT;
1985     case errSSLUnknownRootCert:
1986       failf(data, "SSL certificate problem: Untrusted root certificate");
1987       return CURLE_SSL_CACERT;
1988     case errSSLNoRootCert:
1989       failf(data, "SSL certificate problem: No root certificate");
1990       return CURLE_SSL_CACERT;
1991     case errSSLCertExpired:
1992       failf(data, "SSL certificate problem: Certificate chain had an "
1993             "expired certificate");
1994       return CURLE_SSL_CACERT;
1995     case errSSLBadCert:
1996       failf(data, "SSL certificate problem: Couldn't understand the server "
1997             "certificate format");
1998       return CURLE_SSL_CONNECT_ERROR;
1999     case errSSLHostNameMismatch:
2000       failf(data, "SSL certificate peer hostname mismatch");
2001       return CURLE_PEER_FAILED_VERIFICATION;
2002     default:
2003       failf(data, "SSL unexpected certificate error %d", err);
2004       return CURLE_SSL_CACERT;
2005   }
2006 }
2007 
2008 static int append_cert_to_array(struct Curl_easy *data,
2009                                 unsigned char *buf, size_t buflen,
2010                                 CFMutableArrayRef array)
2011 {
2012     CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
2013     char *certp;
2014     CURLcode result;
2015     if(!certdata) {
2016       failf(data, "SSL: failed to allocate array for CA certificate");
2017       return CURLE_OUT_OF_MEMORY;
2018     }
2019 
2020     SecCertificateRef cacert =
2021       SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
2022     CFRelease(certdata);
2023     if(!cacert) {
2024       failf(data, "SSL: failed to create SecCertificate from CA certificate");
2025       return CURLE_SSL_CACERT;
2026     }
2027 
2028     /* Check if cacert is valid. */
2029     result = CopyCertSubject(data, cacert, &certp);
2030     if(result)
2031       return result;
2032     free(certp);
2033 
2034     CFArrayAppendValue(array, cacert);
2035     CFRelease(cacert);
2036 
2037     return CURLE_OK;
2038 }
2039 
2040 static int verify_cert(const char *cafile, struct Curl_easy *data,
2041                        SSLContextRef ctx)
2042 {
2043   int n = 0, rc;
2044   long res;
2045   unsigned char *certbuf, *der;
2046   size_t buflen, derlen, offset = 0;
2047 
2048   if(read_cert(cafile, &certbuf, &buflen) < 0) {
2049     failf(data, "SSL: failed to read or invalid CA certificate");
2050     return CURLE_SSL_CACERT;
2051   }
2052 
2053   /*
2054    * Certbuf now contains the contents of the certificate file, which can be
2055    * - a single DER certificate,
2056    * - a single PEM certificate or
2057    * - a bunch of PEM certificates (certificate bundle).
2058    *
2059    * Go through certbuf, and convert any PEM certificate in it into DER
2060    * format.
2061    */
2062   CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
2063                                                  &kCFTypeArrayCallBacks);
2064   if(array == NULL) {
2065     free(certbuf);
2066     failf(data, "SSL: out of memory creating CA certificate array");
2067     return CURLE_OUT_OF_MEMORY;
2068   }
2069 
2070   while(offset < buflen) {
2071     n++;
2072 
2073     /*
2074      * Check if the certificate is in PEM format, and convert it to DER. If
2075      * this fails, we assume the certificate is in DER format.
2076      */
2077     res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
2078     if(res < 0) {
2079       free(certbuf);
2080       CFRelease(array);
2081       failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
2082             n, offset);
2083       return CURLE_SSL_CACERT;
2084     }
2085     offset += res;
2086 
2087     if(res == 0 && offset == 0) {
2088       /* This is not a PEM file, probably a certificate in DER format. */
2089       rc = append_cert_to_array(data, certbuf, buflen, array);
2090       free(certbuf);
2091       if(rc != CURLE_OK) {
2092         CFRelease(array);
2093         return rc;
2094       }
2095       break;
2096     }
2097     else if(res == 0) {
2098       /* No more certificates in the bundle. */
2099       free(certbuf);
2100       break;
2101     }
2102 
2103     rc = append_cert_to_array(data, der, derlen, array);
2104     free(der);
2105     if(rc != CURLE_OK) {
2106       free(certbuf);
2107       CFRelease(array);
2108       return rc;
2109     }
2110   }
2111 
2112   SecTrustRef trust;
2113   OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2114   if(trust == NULL) {
2115     failf(data, "SSL: error getting certificate chain");
2116     CFRelease(array);
2117     return CURLE_OUT_OF_MEMORY;
2118   }
2119   else if(ret != noErr) {
2120     CFRelease(array);
2121     return sslerr_to_curlerr(data, ret);
2122   }
2123 
2124   ret = SecTrustSetAnchorCertificates(trust, array);
2125   if(ret != noErr) {
2126     CFRelease(trust);
2127     return sslerr_to_curlerr(data, ret);
2128   }
2129   ret = SecTrustSetAnchorCertificatesOnly(trust, true);
2130   if(ret != noErr) {
2131     CFRelease(trust);
2132     return sslerr_to_curlerr(data, ret);
2133   }
2134 
2135   SecTrustResultType trust_eval = 0;
2136   ret = SecTrustEvaluate(trust, &trust_eval);
2137   CFRelease(array);
2138   CFRelease(trust);
2139   if(ret != noErr) {
2140     return sslerr_to_curlerr(data, ret);
2141   }
2142 
2143   switch(trust_eval) {
2144     case kSecTrustResultUnspecified:
2145     case kSecTrustResultProceed:
2146       return CURLE_OK;
2147 
2148     case kSecTrustResultRecoverableTrustFailure:
2149     case kSecTrustResultDeny:
2150     default:
2151       failf(data, "SSL: certificate verification failed (result: %d)",
2152             trust_eval);
2153       return CURLE_PEER_FAILED_VERIFICATION;
2154   }
2155 }
2156 
2157 #ifdef DARWIN_SSL_PINNEDPUBKEY
2158 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
2159                                     SSLContextRef ctx,
2160                                     const char *pinnedpubkey)
2161 {  /* Scratch */
2162   size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24;
2163   unsigned char *pubkey = NULL, *realpubkey = NULL;
2164   const unsigned char *spkiHeader = NULL;
2165   CFDataRef publicKeyBits = NULL;
2166 
2167   /* Result is returned to caller */
2168   CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
2169 
2170   /* if a path wasn't specified, don't pin */
2171   if(!pinnedpubkey)
2172     return CURLE_OK;
2173 
2174 
2175   if(!ctx)
2176     return result;
2177 
2178   do {
2179     SecTrustRef trust;
2180     OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2181     if(ret != noErr || trust == NULL)
2182       break;
2183 
2184     SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
2185     CFRelease(trust);
2186     if(keyRef == NULL)
2187       break;
2188 
2189 #ifdef DARWIN_SSL_PINNEDPUBKEY_V1
2190 
2191     publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL);
2192     CFRelease(keyRef);
2193     if(publicKeyBits == NULL)
2194       break;
2195 
2196 #elif DARWIN_SSL_PINNEDPUBKEY_V2
2197 
2198     OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL,
2199                                      &publicKeyBits);
2200     CFRelease(keyRef);
2201     if(success != errSecSuccess || publicKeyBits == NULL)
2202       break;
2203 
2204 #endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
2205 
2206     pubkeylen = CFDataGetLength(publicKeyBits);
2207     pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits);
2208 
2209     switch(pubkeylen) {
2210       case 526:
2211         /* 4096 bit RSA pubkeylen == 526 */
2212         spkiHeader = rsa4096SpkiHeader;
2213         break;
2214       case 270:
2215         /* 2048 bit RSA pubkeylen == 270 */
2216         spkiHeader = rsa2048SpkiHeader;
2217         break;
2218 #ifdef DARWIN_SSL_PINNEDPUBKEY_V1
2219       case 65:
2220         /* ecDSA secp256r1 pubkeylen == 65 */
2221         spkiHeader = ecDsaSecp256r1SpkiHeader;
2222         spkiHeaderLength = 26;
2223         break;
2224       case 97:
2225         /* ecDSA secp384r1 pubkeylen == 97 */
2226         spkiHeader = ecDsaSecp384r1SpkiHeader;
2227         spkiHeaderLength = 23;
2228         break;
2229       default:
2230         infof(data, "SSL: unhandled public key length: %d\n", pubkeylen);
2231 #elif DARWIN_SSL_PINNEDPUBKEY_V2
2232       default:
2233         /* ecDSA secp256r1 pubkeylen == 91 header already included?
2234          * ecDSA secp384r1 header already included too
2235          * we assume rest of algorithms do same, so do nothing
2236          */
2237         result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey,
2238                                     pubkeylen);
2239 #endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
2240         continue; /* break from loop */
2241     }
2242 
2243     realpubkeylen = pubkeylen + spkiHeaderLength;
2244     realpubkey = malloc(realpubkeylen);
2245     if(!realpubkey)
2246       break;
2247 
2248     memcpy(realpubkey, spkiHeader, spkiHeaderLength);
2249     memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen);
2250 
2251     result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey,
2252                                   realpubkeylen);
2253 
2254   } while(0);
2255 
2256   Curl_safefree(realpubkey);
2257   if(publicKeyBits != NULL)
2258     CFRelease(publicKeyBits);
2259 
2260   return result;
2261 }
2262 #endif /* DARWIN_SSL_PINNEDPUBKEY */
2263 
2264 static CURLcode
2265 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
2266 {
2267   struct Curl_easy *data = conn->data;
2268   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2269   OSStatus err;
2270   SSLCipherSuite cipher;
2271   SSLProtocol protocol = 0;
2272   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
2273     conn->host.name;
2274 
2275   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
2276               || ssl_connect_2_reading == connssl->connecting_state
2277               || ssl_connect_2_writing == connssl->connecting_state);
2278 
2279   /* Here goes nothing: */
2280   err = SSLHandshake(BACKEND->ssl_ctx);
2281 
2282   if(err != noErr) {
2283     switch(err) {
2284       case errSSLWouldBlock:  /* they're not done with us yet */
2285         connssl->connecting_state = BACKEND->ssl_direction ?
2286             ssl_connect_2_writing : ssl_connect_2_reading;
2287         return CURLE_OK;
2288 
2289       /* The below is errSSLServerAuthCompleted; it's not defined in
2290         Leopard's headers */
2291       case -9841:
2292         if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
2293           int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
2294                                 BACKEND->ssl_ctx);
2295           if(res != CURLE_OK)
2296             return res;
2297         }
2298         /* the documentation says we need to call SSLHandshake() again */
2299         return darwinssl_connect_step2(conn, sockindex);
2300 
2301       /* These are all certificate problems with the server: */
2302       case errSSLXCertChainInvalid:
2303         failf(data, "SSL certificate problem: Invalid certificate chain");
2304         return CURLE_SSL_CACERT;
2305       case errSSLUnknownRootCert:
2306         failf(data, "SSL certificate problem: Untrusted root certificate");
2307         return CURLE_SSL_CACERT;
2308       case errSSLNoRootCert:
2309         failf(data, "SSL certificate problem: No root certificate");
2310         return CURLE_SSL_CACERT;
2311       case errSSLCertExpired:
2312         failf(data, "SSL certificate problem: Certificate chain had an "
2313               "expired certificate");
2314         return CURLE_SSL_CACERT;
2315       case errSSLBadCert:
2316         failf(data, "SSL certificate problem: Couldn't understand the server "
2317               "certificate format");
2318         return CURLE_SSL_CONNECT_ERROR;
2319 
2320       /* These are all certificate problems with the client: */
2321       case errSecAuthFailed:
2322         failf(data, "SSL authentication failed");
2323         return CURLE_SSL_CONNECT_ERROR;
2324       case errSSLPeerHandshakeFail:
2325         failf(data, "SSL peer handshake failed, the server most likely "
2326               "requires a client certificate to connect");
2327         return CURLE_SSL_CONNECT_ERROR;
2328       case errSSLPeerUnknownCA:
2329         failf(data, "SSL server rejected the client certificate due to "
2330               "the certificate being signed by an unknown certificate "
2331               "authority");
2332         return CURLE_SSL_CONNECT_ERROR;
2333 
2334       /* This error is raised if the server's cert didn't match the server's
2335          host name: */
2336       case errSSLHostNameMismatch:
2337         failf(data, "SSL certificate peer verification failed, the "
2338               "certificate did not match \"%s\"\n", conn->host.dispname);
2339         return CURLE_PEER_FAILED_VERIFICATION;
2340 
2341       /* Generic handshake errors: */
2342       case errSSLConnectionRefused:
2343         failf(data, "Server dropped the connection during the SSL handshake");
2344         return CURLE_SSL_CONNECT_ERROR;
2345       case errSSLClosedAbort:
2346         failf(data, "Server aborted the SSL handshake");
2347         return CURLE_SSL_CONNECT_ERROR;
2348       case errSSLNegotiation:
2349         failf(data, "Could not negotiate an SSL cipher suite with the server");
2350         return CURLE_SSL_CONNECT_ERROR;
2351       /* Sometimes paramErr happens with buggy ciphers: */
2352       case paramErr: case errSSLInternal:
2353         failf(data, "Internal SSL engine error encountered during the "
2354               "SSL handshake");
2355         return CURLE_SSL_CONNECT_ERROR;
2356       case errSSLFatalAlert:
2357         failf(data, "Fatal SSL engine error encountered during the SSL "
2358               "handshake");
2359         return CURLE_SSL_CONNECT_ERROR;
2360       default:
2361         failf(data, "Unknown SSL protocol error in connection to %s:%d",
2362               hostname, err);
2363         return CURLE_SSL_CONNECT_ERROR;
2364     }
2365   }
2366   else {
2367     /* we have been connected fine, we're not waiting for anything else. */
2368     connssl->connecting_state = ssl_connect_3;
2369 
2370 #ifdef DARWIN_SSL_PINNEDPUBKEY
2371     if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
2372       CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
2373                             data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
2374       if(result) {
2375         failf(data, "SSL: public key does not match pinned public key!");
2376         return result;
2377       }
2378     }
2379 #endif /* DARWIN_SSL_PINNEDPUBKEY */
2380 
2381     /* Informational message */
2382     (void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher);
2383     (void)SSLGetNegotiatedProtocolVersion(BACKEND->ssl_ctx, &protocol);
2384     switch(protocol) {
2385       case kSSLProtocol2:
2386         infof(data, "SSL 2.0 connection using %s\n",
2387               SSLCipherNameForNumber(cipher));
2388         break;
2389       case kSSLProtocol3:
2390         infof(data, "SSL 3.0 connection using %s\n",
2391               SSLCipherNameForNumber(cipher));
2392         break;
2393       case kTLSProtocol1:
2394         infof(data, "TLS 1.0 connection using %s\n",
2395               TLSCipherNameForNumber(cipher));
2396         break;
2397 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2398       case kTLSProtocol11:
2399         infof(data, "TLS 1.1 connection using %s\n",
2400               TLSCipherNameForNumber(cipher));
2401         break;
2402       case kTLSProtocol12:
2403         infof(data, "TLS 1.2 connection using %s\n",
2404               TLSCipherNameForNumber(cipher));
2405         break;
2406 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2407 #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
2408       case kTLSProtocol13:
2409         infof(data, "TLS 1.3 connection using %s\n",
2410               TLSCipherNameForNumber(cipher));
2411         break;
2412 #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
2413       default:
2414         infof(data, "Unknown protocol connection\n");
2415         break;
2416     }
2417 
2418     return CURLE_OK;
2419   }
2420 }
2421 
2422 #ifndef CURL_DISABLE_VERBOSE_STRINGS
2423 /* This should be called during step3 of the connection at the earliest */
2424 static void
2425 show_verbose_server_cert(struct connectdata *conn,
2426                          int sockindex)
2427 {
2428   struct Curl_easy *data = conn->data;
2429   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2430   CFArrayRef server_certs = NULL;
2431   SecCertificateRef server_cert;
2432   OSStatus err;
2433   CFIndex i, count;
2434   SecTrustRef trust = NULL;
2435 
2436   if(!BACKEND->ssl_ctx)
2437     return;
2438 
2439 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
2440 #if CURL_BUILD_IOS
2441 #pragma unused(server_certs)
2442   err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
2443   /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2444      a null trust, so be on guard for that: */
2445   if(err == noErr && trust) {
2446     count = SecTrustGetCertificateCount(trust);
2447     for(i = 0L ; i < count ; i++) {
2448       CURLcode result;
2449       char *certp;
2450       server_cert = SecTrustGetCertificateAtIndex(trust, i);
2451       result = CopyCertSubject(data, server_cert, &certp);
2452       if(!result) {
2453         infof(data, "Server certificate: %s\n", certp);
2454         free(certp);
2455       }
2456     }
2457     CFRelease(trust);
2458   }
2459 #else
2460   /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
2461      The function SecTrustGetCertificateAtIndex() is officially present
2462      in Lion, but it is unfortunately also present in Snow Leopard as
2463      private API and doesn't work as expected. So we have to look for
2464      a different symbol to make sure this code is only executed under
2465      Lion or later. */
2466   if(SecTrustEvaluateAsync != NULL) {
2467 #pragma unused(server_certs)
2468     err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
2469     /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2470        a null trust, so be on guard for that: */
2471     if(err == noErr && trust) {
2472       count = SecTrustGetCertificateCount(trust);
2473       for(i = 0L ; i < count ; i++) {
2474         char *certp;
2475         CURLcode result;
2476         server_cert = SecTrustGetCertificateAtIndex(trust, i);
2477         result = CopyCertSubject(data, server_cert, &certp);
2478         if(!result) {
2479           infof(data, "Server certificate: %s\n", certp);
2480           free(certp);
2481         }
2482       }
2483       CFRelease(trust);
2484     }
2485   }
2486   else {
2487 #if CURL_SUPPORT_MAC_10_8
2488     err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
2489     /* Just in case SSLCopyPeerCertificates() returns null too... */
2490     if(err == noErr && server_certs) {
2491       count = CFArrayGetCount(server_certs);
2492       for(i = 0L ; i < count ; i++) {
2493         char *certp;
2494         CURLcode result;
2495         server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
2496                                                                 i);
2497         result = CopyCertSubject(data, server_cert, &certp);
2498         if(!result) {
2499           infof(data, "Server certificate: %s\n", certp);
2500           free(certp);
2501         }
2502       }
2503       CFRelease(server_certs);
2504     }
2505 #endif /* CURL_SUPPORT_MAC_10_8 */
2506   }
2507 #endif /* CURL_BUILD_IOS */
2508 #else
2509 #pragma unused(trust)
2510   err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
2511   if(err == noErr) {
2512     count = CFArrayGetCount(server_certs);
2513     for(i = 0L ; i < count ; i++) {
2514       CURLcode result;
2515       char *certp;
2516       server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
2517       result = CopyCertSubject(data, server_cert, &certp);
2518       if(!result) {
2519         infof(data, "Server certificate: %s\n", certp);
2520         free(certp);
2521       }
2522     }
2523     CFRelease(server_certs);
2524   }
2525 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
2526 }
2527 #endif /* !CURL_DISABLE_VERBOSE_STRINGS */
2528 
2529 static CURLcode
2530 darwinssl_connect_step3(struct connectdata *conn,
2531                         int sockindex)
2532 {
2533   struct Curl_easy *data = conn->data;
2534   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2535 
2536   /* There is no step 3!
2537    * Well, okay, if verbose mode is on, let's print the details of the
2538    * server certificates. */
2539 #ifndef CURL_DISABLE_VERBOSE_STRINGS
2540   if(data->set.verbose)
2541     show_verbose_server_cert(conn, sockindex);
2542 #endif
2543 
2544   connssl->connecting_state = ssl_connect_done;
2545   return CURLE_OK;
2546 }
2547 
2548 static Curl_recv darwinssl_recv;
2549 static Curl_send darwinssl_send;
2550 
2551 static CURLcode
2552 darwinssl_connect_common(struct connectdata *conn,
2553                          int sockindex,
2554                          bool nonblocking,
2555                          bool *done)
2556 {
2557   CURLcode result;
2558   struct Curl_easy *data = conn->data;
2559   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2560   curl_socket_t sockfd = conn->sock[sockindex];
2561   long timeout_ms;
2562   int what;
2563 
2564   /* check if the connection has already been established */
2565   if(ssl_connection_complete == connssl->state) {
2566     *done = TRUE;
2567     return CURLE_OK;
2568   }
2569 
2570   if(ssl_connect_1 == connssl->connecting_state) {
2571     /* Find out how much more time we're allowed */
2572     timeout_ms = Curl_timeleft(data, NULL, TRUE);
2573 
2574     if(timeout_ms < 0) {
2575       /* no need to continue if time already is up */
2576       failf(data, "SSL connection timeout");
2577       return CURLE_OPERATION_TIMEDOUT;
2578     }
2579 
2580     result = darwinssl_connect_step1(conn, sockindex);
2581     if(result)
2582       return result;
2583   }
2584 
2585   while(ssl_connect_2 == connssl->connecting_state ||
2586         ssl_connect_2_reading == connssl->connecting_state ||
2587         ssl_connect_2_writing == connssl->connecting_state) {
2588 
2589     /* check allowed time left */
2590     timeout_ms = Curl_timeleft(data, NULL, TRUE);
2591 
2592     if(timeout_ms < 0) {
2593       /* no need to continue if time already is up */
2594       failf(data, "SSL connection timeout");
2595       return CURLE_OPERATION_TIMEDOUT;
2596     }
2597 
2598     /* if ssl is expecting something, check if it's available. */
2599     if(connssl->connecting_state == ssl_connect_2_reading ||
2600        connssl->connecting_state == ssl_connect_2_writing) {
2601 
2602       curl_socket_t writefd = ssl_connect_2_writing ==
2603       connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2604       curl_socket_t readfd = ssl_connect_2_reading ==
2605       connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2606 
2607       what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
2608                                nonblocking?0:timeout_ms);
2609       if(what < 0) {
2610         /* fatal error */
2611         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2612         return CURLE_SSL_CONNECT_ERROR;
2613       }
2614       else if(0 == what) {
2615         if(nonblocking) {
2616           *done = FALSE;
2617           return CURLE_OK;
2618         }
2619         else {
2620           /* timeout */
2621           failf(data, "SSL connection timeout");
2622           return CURLE_OPERATION_TIMEDOUT;
2623         }
2624       }
2625       /* socket is readable or writable */
2626     }
2627 
2628     /* Run transaction, and return to the caller if it failed or if this
2629      * connection is done nonblocking and this loop would execute again. This
2630      * permits the owner of a multi handle to abort a connection attempt
2631      * before step2 has completed while ensuring that a client using select()
2632      * or epoll() will always have a valid fdset to wait on.
2633      */
2634     result = darwinssl_connect_step2(conn, sockindex);
2635     if(result || (nonblocking &&
2636                   (ssl_connect_2 == connssl->connecting_state ||
2637                    ssl_connect_2_reading == connssl->connecting_state ||
2638                    ssl_connect_2_writing == connssl->connecting_state)))
2639       return result;
2640 
2641   } /* repeat step2 until all transactions are done. */
2642 
2643 
2644   if(ssl_connect_3 == connssl->connecting_state) {
2645     result = darwinssl_connect_step3(conn, sockindex);
2646     if(result)
2647       return result;
2648   }
2649 
2650   if(ssl_connect_done == connssl->connecting_state) {
2651     connssl->state = ssl_connection_complete;
2652     conn->recv[sockindex] = darwinssl_recv;
2653     conn->send[sockindex] = darwinssl_send;
2654     *done = TRUE;
2655   }
2656   else
2657     *done = FALSE;
2658 
2659   /* Reset our connect state machine */
2660   connssl->connecting_state = ssl_connect_1;
2661 
2662   return CURLE_OK;
2663 }
2664 
2665 static CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
2666                                                    int sockindex, bool *done)
2667 {
2668   return darwinssl_connect_common(conn, sockindex, TRUE, done);
2669 }
2670 
2671 static CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex)
2672 {
2673   CURLcode result;
2674   bool done = FALSE;
2675 
2676   result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
2677 
2678   if(result)
2679     return result;
2680 
2681   DEBUGASSERT(done);
2682 
2683   return CURLE_OK;
2684 }
2685 
2686 static void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
2687 {
2688   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2689 
2690   if(BACKEND->ssl_ctx) {
2691     (void)SSLClose(BACKEND->ssl_ctx);
2692 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2693     if(SSLCreateContext != NULL)
2694       CFRelease(BACKEND->ssl_ctx);
2695 #if CURL_SUPPORT_MAC_10_8
2696     else
2697       (void)SSLDisposeContext(BACKEND->ssl_ctx);
2698 #endif  /* CURL_SUPPORT_MAC_10_8 */
2699 #else
2700     (void)SSLDisposeContext(BACKEND->ssl_ctx);
2701 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2702     BACKEND->ssl_ctx = NULL;
2703   }
2704   BACKEND->ssl_sockfd = 0;
2705 }
2706 
2707 static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
2708 {
2709   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2710   struct Curl_easy *data = conn->data;
2711   ssize_t nread;
2712   int what;
2713   int rc;
2714   char buf[120];
2715 
2716   if(!BACKEND->ssl_ctx)
2717     return 0;
2718 
2719   if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
2720     return 0;
2721 
2722   Curl_darwinssl_close(conn, sockindex);
2723 
2724   rc = 0;
2725 
2726   what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
2727 
2728   for(;;) {
2729     if(what < 0) {
2730       /* anything that gets here is fatally bad */
2731       failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2732       rc = -1;
2733       break;
2734     }
2735 
2736     if(!what) {                                /* timeout */
2737       failf(data, "SSL shutdown timeout");
2738       break;
2739     }
2740 
2741     /* Something to read, let's do it and hope that it is the close
2742      notify alert from the server. No way to SSL_Read now, so use read(). */
2743 
2744     nread = read(conn->sock[sockindex], buf, sizeof(buf));
2745 
2746     if(nread < 0) {
2747       failf(data, "read: %s", strerror(errno));
2748       rc = -1;
2749     }
2750 
2751     if(nread <= 0)
2752       break;
2753 
2754     what = SOCKET_READABLE(conn->sock[sockindex], 0);
2755   }
2756 
2757   return rc;
2758 }
2759 
2760 static void Curl_darwinssl_session_free(void *ptr)
2761 {
2762   /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
2763      cached session ID inside the Security framework. There is a private
2764      function that does this, but I don't want to have to explain to you why I
2765      got your application rejected from the App Store due to the use of a
2766      private API, so the best we can do is free up our own char array that we
2767      created way back in darwinssl_connect_step1... */
2768   Curl_safefree(ptr);
2769 }
2770 
2771 static size_t Curl_darwinssl_version(char *buffer, size_t size)
2772 {
2773   return snprintf(buffer, size, "SecureTransport");
2774 }
2775 
2776 /*
2777  * This function uses SSLGetSessionState to determine connection status.
2778  *
2779  * Return codes:
2780  *     1 means the connection is still in place
2781  *     0 means the connection has been closed
2782  *    -1 means the connection status is unknown
2783  */
2784 static int Curl_darwinssl_check_cxn(struct connectdata *conn)
2785 {
2786   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2787   OSStatus err;
2788   SSLSessionState state;
2789 
2790   if(BACKEND->ssl_ctx) {
2791     err = SSLGetSessionState(BACKEND->ssl_ctx, &state);
2792     if(err == noErr)
2793       return state == kSSLConnected || state == kSSLHandshake;
2794     return -1;
2795   }
2796   return 0;
2797 }
2798 
2799 static bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2800                                         int connindex)
2801 {
2802   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2803   OSStatus err;
2804   size_t buffer;
2805 
2806   if(BACKEND->ssl_ctx) {  /* SSL is in use */
2807     err = SSLGetBufferedReadSize(BACKEND->ssl_ctx, &buffer);
2808     if(err == noErr)
2809       return buffer > 0UL;
2810     return false;
2811   }
2812   else
2813     return false;
2814 }
2815 
2816 static CURLcode Curl_darwinssl_random(struct Curl_easy *data UNUSED_PARAM,
2817                                       unsigned char *entropy, size_t length)
2818 {
2819   /* arc4random_buf() isn't available on cats older than Lion, so let's
2820      do this manually for the benefit of the older cats. */
2821   size_t i;
2822   u_int32_t random_number = 0;
2823 
2824   (void)data;
2825 
2826   for(i = 0 ; i < length ; i++) {
2827     if(i % sizeof(u_int32_t) == 0)
2828       random_number = arc4random();
2829     entropy[i] = random_number & 0xFF;
2830     random_number >>= 8;
2831   }
2832   i = random_number = 0;
2833   return CURLE_OK;
2834 }
2835 
2836 static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2837                                       size_t tmplen,
2838                                       unsigned char *md5sum, /* output */
2839                                       size_t md5len)
2840 {
2841   (void)md5len;
2842   (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2843   return CURLE_OK;
2844 }
2845 
2846 static void Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */
2847                                      size_t tmplen,
2848                                      unsigned char *sha256sum, /* output */
2849                                      size_t sha256len)
2850 {
2851   assert(sha256len >= CURL_SHA256_DIGEST_LENGTH);
2852   (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum);
2853 }
2854 
2855 static bool Curl_darwinssl_false_start(void)
2856 {
2857 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
2858   if(SSLSetSessionOption != NULL)
2859     return TRUE;
2860 #endif
2861   return FALSE;
2862 }
2863 
2864 static ssize_t darwinssl_send(struct connectdata *conn,
2865                               int sockindex,
2866                               const void *mem,
2867                               size_t len,
2868                               CURLcode *curlcode)
2869 {
2870   /*struct Curl_easy *data = conn->data;*/
2871   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2872   size_t processed = 0UL;
2873   OSStatus err;
2874 
2875   /* The SSLWrite() function works a little differently than expected. The
2876      fourth argument (processed) is currently documented in Apple's
2877      documentation as: "On return, the length, in bytes, of the data actually
2878      written."
2879 
2880      Now, one could interpret that as "written to the socket," but actually,
2881      it returns the amount of data that was written to a buffer internal to
2882      the SSLContextRef instead. So it's possible for SSLWrite() to return
2883      errSSLWouldBlock and a number of bytes "written" because those bytes were
2884      encrypted and written to a buffer, not to the socket.
2885 
2886      So if this happens, then we need to keep calling SSLWrite() over and
2887      over again with no new data until it quits returning errSSLWouldBlock. */
2888 
2889   /* Do we have buffered data to write from the last time we were called? */
2890   if(BACKEND->ssl_write_buffered_length) {
2891     /* Write the buffered data: */
2892     err = SSLWrite(BACKEND->ssl_ctx, NULL, 0UL, &processed);
2893     switch(err) {
2894       case noErr:
2895         /* processed is always going to be 0 because we didn't write to
2896            the buffer, so return how much was written to the socket */
2897         processed = BACKEND->ssl_write_buffered_length;
2898         BACKEND->ssl_write_buffered_length = 0UL;
2899         break;
2900       case errSSLWouldBlock: /* argh, try again */
2901         *curlcode = CURLE_AGAIN;
2902         return -1L;
2903       default:
2904         failf(conn->data, "SSLWrite() returned error %d", err);
2905         *curlcode = CURLE_SEND_ERROR;
2906         return -1L;
2907     }
2908   }
2909   else {
2910     /* We've got new data to write: */
2911     err = SSLWrite(BACKEND->ssl_ctx, mem, len, &processed);
2912     if(err != noErr) {
2913       switch(err) {
2914         case errSSLWouldBlock:
2915           /* Data was buffered but not sent, we have to tell the caller
2916              to try sending again, and remember how much was buffered */
2917           BACKEND->ssl_write_buffered_length = len;
2918           *curlcode = CURLE_AGAIN;
2919           return -1L;
2920         default:
2921           failf(conn->data, "SSLWrite() returned error %d", err);
2922           *curlcode = CURLE_SEND_ERROR;
2923           return -1L;
2924       }
2925     }
2926   }
2927   return (ssize_t)processed;
2928 }
2929 
2930 static ssize_t darwinssl_recv(struct connectdata *conn,
2931                               int num,
2932                               char *buf,
2933                               size_t buffersize,
2934                               CURLcode *curlcode)
2935 {
2936   /*struct Curl_easy *data = conn->data;*/
2937   struct ssl_connect_data *connssl = &conn->ssl[num];
2938   size_t processed = 0UL;
2939   OSStatus err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed);
2940 
2941   if(err != noErr) {
2942     switch(err) {
2943       case errSSLWouldBlock:  /* return how much we read (if anything) */
2944         if(processed)
2945           return (ssize_t)processed;
2946         *curlcode = CURLE_AGAIN;
2947         return -1L;
2948         break;
2949 
2950       /* errSSLClosedGraceful - server gracefully shut down the SSL session
2951          errSSLClosedNoNotify - server hung up on us instead of sending a
2952            closure alert notice, read() is returning 0
2953          Either way, inform the caller that the server disconnected. */
2954       case errSSLClosedGraceful:
2955       case errSSLClosedNoNotify:
2956         *curlcode = CURLE_OK;
2957         return -1L;
2958         break;
2959 
2960       default:
2961         failf(conn->data, "SSLRead() return error %d", err);
2962         *curlcode = CURLE_RECV_ERROR;
2963         return -1L;
2964         break;
2965     }
2966   }
2967   return (ssize_t)processed;
2968 }
2969 
2970 static void *Curl_darwinssl_get_internals(struct ssl_connect_data *connssl,
2971                                           CURLINFO info UNUSED_PARAM)
2972 {
2973   (void)info;
2974   return BACKEND->ssl_ctx;
2975 }
2976 
2977 const struct Curl_ssl Curl_ssl_darwinssl = {
2978   { CURLSSLBACKEND_DARWINSSL, "darwinssl" }, /* info */
2979 
2980   0, /* have_ca_path */
2981   0, /* have_certinfo */
2982 #ifdef DARWIN_SSL_PINNEDPUBKEY
2983   1, /* have_pinnedpubkey */
2984 #else
2985   0, /* have_pinnedpubkey */
2986 #endif /* DARWIN_SSL_PINNEDPUBKEY */
2987   0, /* have_ssl_ctx */
2988   0, /* support_https_proxy */
2989 
2990   sizeof(struct ssl_backend_data),
2991 
2992   Curl_none_init,                     /* init */
2993   Curl_none_cleanup,                  /* cleanup */
2994   Curl_darwinssl_version,             /* version */
2995   Curl_darwinssl_check_cxn,           /* check_cxn */
2996   Curl_darwinssl_shutdown,            /* shutdown */
2997   Curl_darwinssl_data_pending,        /* data_pending */
2998   Curl_darwinssl_random,              /* random */
2999   Curl_none_cert_status_request,      /* cert_status_request */
3000   Curl_darwinssl_connect,             /* connect */
3001   Curl_darwinssl_connect_nonblocking, /* connect_nonblocking */
3002   Curl_darwinssl_get_internals,       /* get_internals */
3003   Curl_darwinssl_close,               /* close_one */
3004   Curl_none_close_all,                /* close_all */
3005   Curl_darwinssl_session_free,        /* session_free */
3006   Curl_none_set_engine,               /* set_engine */
3007   Curl_none_set_engine_default,       /* set_engine_default */
3008   Curl_none_engines_list,             /* engines_list */
3009   Curl_darwinssl_false_start,         /* false_start */
3010   Curl_darwinssl_md5sum,              /* md5sum */
3011   Curl_darwinssl_sha256sum            /* sha256sum */
3012 };
3013 
3014 #ifdef __clang__
3015 #pragma clang diagnostic pop
3016 #endif
3017 
3018 #endif /* USE_DARWINSSL */
3019