darwinssl: Updated copyright following recent changes
[platform/upstream/curl.git] / lib / vtls / curl_darwinssl.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
9  * Copyright (C) 2012 - 2014, 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 http://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 Mac OS X 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 #ifdef USE_DARWINSSL
32
33 #ifdef HAVE_LIMITS_H
34 #include <limits.h>
35 #endif
36
37 #include <Security/Security.h>
38 #include <Security/SecureTransport.h>
39 #include <CoreFoundation/CoreFoundation.h>
40 #include <CommonCrypto/CommonDigest.h>
41
42 /* The Security framework has changed greatly between iOS and different OS X
43    versions, and we will try to support as many of them as we can (back to
44    Leopard and iOS 5) by using macros and weak-linking.
45
46    IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
47    you must build this project against the 10.8 SDK or later. */
48 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
49
50 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
51 #error "The darwinssl back-end requires Leopard or later."
52 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
53
54 #define CURL_BUILD_IOS 0
55 #define CURL_BUILD_IOS_7 0
56 #define CURL_BUILD_MAC 1
57 /* This is the maximum API level we are allowed to use when building: */
58 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
59 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
60 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
61 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
62 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
63 /* These macros mean "the following code is present to allow runtime backward
64    compatibility with at least this cat or earlier":
65    (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
66    environmental variable.) */
67 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
68 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
69 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
70 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
71 #define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
72
73 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
74 #define CURL_BUILD_IOS 1
75 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
76 #define CURL_BUILD_MAC 0
77 #define CURL_BUILD_MAC_10_5 0
78 #define CURL_BUILD_MAC_10_6 0
79 #define CURL_BUILD_MAC_10_7 0
80 #define CURL_BUILD_MAC_10_8 0
81 #define CURL_SUPPORT_MAC_10_5 0
82 #define CURL_SUPPORT_MAC_10_6 0
83 #define CURL_SUPPORT_MAC_10_7 0
84 #define CURL_SUPPORT_MAC_10_8 0
85
86 #else
87 #error "The darwinssl back-end requires iOS or OS X."
88 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
89
90 #if CURL_BUILD_MAC
91 #include <sys/sysctl.h>
92 #endif /* CURL_BUILD_MAC */
93
94 #include "urldata.h"
95 #include "sendf.h"
96 #include "inet_pton.h"
97 #include "connect.h"
98 #include "select.h"
99 #include "vtls.h"
100 #include "curl_darwinssl.h"
101
102 #define _MPRINTF_REPLACE /* use our functions only */
103 #include <curl/mprintf.h>
104
105 #include "curl_memory.h"
106 /* The last #include file should be: */
107 #include "memdebug.h"
108
109 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
110 #define ioErr -36
111 #define paramErr -50
112
113 /* The following two functions were ripped from Apple sample code,
114  * with some modifications: */
115 static OSStatus SocketRead(SSLConnectionRef connection,
116                            void *data,          /* owned by
117                                                  * caller, data
118                                                  * RETURNED */
119                            size_t *dataLength)  /* IN/OUT */
120 {
121   size_t bytesToGo = *dataLength;
122   size_t initLen = bytesToGo;
123   UInt8 *currData = (UInt8 *)data;
124   /*int sock = *(int *)connection;*/
125   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
126   int sock = connssl->ssl_sockfd;
127   OSStatus rtn = noErr;
128   size_t bytesRead;
129   ssize_t rrtn;
130   int theErr;
131
132   *dataLength = 0;
133
134   for(;;) {
135     bytesRead = 0;
136     rrtn = read(sock, currData, bytesToGo);
137     if(rrtn <= 0) {
138       /* this is guesswork... */
139       theErr = errno;
140       if(rrtn == 0) { /* EOF = server hung up */
141         /* the framework will turn this into errSSLClosedNoNotify */
142         rtn = errSSLClosedGraceful;
143       }
144       else /* do the switch */
145         switch(theErr) {
146           case ENOENT:
147             /* connection closed */
148             rtn = errSSLClosedGraceful;
149             break;
150           case ECONNRESET:
151             rtn = errSSLClosedAbort;
152             break;
153           case EAGAIN:
154             rtn = errSSLWouldBlock;
155             connssl->ssl_direction = false;
156             break;
157           default:
158             rtn = ioErr;
159             break;
160         }
161       break;
162     }
163     else {
164       bytesRead = rrtn;
165     }
166     bytesToGo -= bytesRead;
167     currData  += bytesRead;
168
169     if(bytesToGo == 0) {
170       /* filled buffer with incoming data, done */
171       break;
172     }
173   }
174   *dataLength = initLen - bytesToGo;
175
176   return rtn;
177 }
178
179 static OSStatus SocketWrite(SSLConnectionRef connection,
180                             const void *data,
181                             size_t *dataLength)  /* IN/OUT */
182 {
183   size_t bytesSent = 0;
184   /*int sock = *(int *)connection;*/
185   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
186   int sock = connssl->ssl_sockfd;
187   ssize_t length;
188   size_t dataLen = *dataLength;
189   const UInt8 *dataPtr = (UInt8 *)data;
190   OSStatus ortn;
191   int theErr;
192
193   *dataLength = 0;
194
195   do {
196     length = write(sock,
197                    (char*)dataPtr + bytesSent,
198                    dataLen - bytesSent);
199   } while((length > 0) &&
200            ( (bytesSent += length) < dataLen) );
201
202   if(length <= 0) {
203     theErr = errno;
204     if(theErr == EAGAIN) {
205       ortn = errSSLWouldBlock;
206       connssl->ssl_direction = true;
207     }
208     else {
209       ortn = ioErr;
210     }
211   }
212   else {
213     ortn = noErr;
214   }
215   *dataLength = bytesSent;
216   return ortn;
217 }
218
219 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
220   switch (cipher) {
221     /* SSL version 3.0 */
222     case SSL_RSA_WITH_NULL_MD5:
223       return "SSL_RSA_WITH_NULL_MD5";
224       break;
225     case SSL_RSA_WITH_NULL_SHA:
226       return "SSL_RSA_WITH_NULL_SHA";
227       break;
228     case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
229       return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
230       break;
231     case SSL_RSA_WITH_RC4_128_MD5:
232       return "SSL_RSA_WITH_RC4_128_MD5";
233       break;
234     case SSL_RSA_WITH_RC4_128_SHA:
235       return "SSL_RSA_WITH_RC4_128_SHA";
236       break;
237     case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
238       return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
239       break;
240     case SSL_RSA_WITH_IDEA_CBC_SHA:
241       return "SSL_RSA_WITH_IDEA_CBC_SHA";
242       break;
243     case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
244       return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
245       break;
246     case SSL_RSA_WITH_DES_CBC_SHA:
247       return "SSL_RSA_WITH_DES_CBC_SHA";
248       break;
249     case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
250       return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
251       break;
252     case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
253       return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
254       break;
255     case SSL_DH_DSS_WITH_DES_CBC_SHA:
256       return "SSL_DH_DSS_WITH_DES_CBC_SHA";
257       break;
258     case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
259       return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
260       break;
261     case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
262       return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
263       break;
264     case SSL_DH_RSA_WITH_DES_CBC_SHA:
265       return "SSL_DH_RSA_WITH_DES_CBC_SHA";
266       break;
267     case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
268       return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
269       break;
270     case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
271       return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
272       break;
273     case SSL_DHE_DSS_WITH_DES_CBC_SHA:
274       return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
275       break;
276     case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
277       return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
278       break;
279     case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
280       return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
281       break;
282     case SSL_DHE_RSA_WITH_DES_CBC_SHA:
283       return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
284       break;
285     case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
286       return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
287       break;
288     case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
289       return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
290       break;
291     case SSL_DH_anon_WITH_RC4_128_MD5:
292       return "SSL_DH_anon_WITH_RC4_128_MD5";
293       break;
294     case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
295       return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
296       break;
297     case SSL_DH_anon_WITH_DES_CBC_SHA:
298       return "SSL_DH_anon_WITH_DES_CBC_SHA";
299       break;
300     case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
301       return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
302       break;
303     case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
304       return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
305       break;
306     case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
307       return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
308       break;
309     /* TLS 1.0 with AES (RFC 3268)
310        (Apparently these are used in SSLv3 implementations as well.) */
311     case TLS_RSA_WITH_AES_128_CBC_SHA:
312       return "TLS_RSA_WITH_AES_128_CBC_SHA";
313       break;
314     case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
315       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
316       break;
317     case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
318       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
319       break;
320     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
321       return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
322       break;
323     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
324       return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
325       break;
326     case TLS_DH_anon_WITH_AES_128_CBC_SHA:
327       return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
328       break;
329     case TLS_RSA_WITH_AES_256_CBC_SHA:
330       return "TLS_RSA_WITH_AES_256_CBC_SHA";
331       break;
332     case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
333       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
334       break;
335     case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
336       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
337       break;
338     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
339       return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
340       break;
341     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
342       return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
343       break;
344     case TLS_DH_anon_WITH_AES_256_CBC_SHA:
345       return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
346       break;
347     /* SSL version 2.0 */
348     case SSL_RSA_WITH_RC2_CBC_MD5:
349       return "SSL_RSA_WITH_RC2_CBC_MD5";
350       break;
351     case SSL_RSA_WITH_IDEA_CBC_MD5:
352       return "SSL_RSA_WITH_IDEA_CBC_MD5";
353       break;
354     case SSL_RSA_WITH_DES_CBC_MD5:
355       return "SSL_RSA_WITH_DES_CBC_MD5";
356       break;
357     case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
358       return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
359       break;
360   }
361   return "SSL_NULL_WITH_NULL_NULL";
362 }
363
364 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
365   switch(cipher) {
366     /* TLS 1.0 with AES (RFC 3268) */
367     case TLS_RSA_WITH_AES_128_CBC_SHA:
368       return "TLS_RSA_WITH_AES_128_CBC_SHA";
369       break;
370     case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
371       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
372       break;
373     case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
374       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
375       break;
376     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
377       return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
378       break;
379     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
380       return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
381       break;
382     case TLS_DH_anon_WITH_AES_128_CBC_SHA:
383       return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
384       break;
385     case TLS_RSA_WITH_AES_256_CBC_SHA:
386       return "TLS_RSA_WITH_AES_256_CBC_SHA";
387       break;
388     case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
389       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
390       break;
391     case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
392       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
393       break;
394     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
395       return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
396       break;
397     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
398       return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
399       break;
400     case TLS_DH_anon_WITH_AES_256_CBC_SHA:
401       return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
402       break;
403 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
404     /* TLS 1.0 with ECDSA (RFC 4492) */
405     case TLS_ECDH_ECDSA_WITH_NULL_SHA:
406       return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
407       break;
408     case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
409       return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
410       break;
411     case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
412       return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
413       break;
414     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
415       return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
416       break;
417     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
418       return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
419       break;
420     case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
421       return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
422       break;
423     case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
424       return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
425       break;
426     case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
427       return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
428       break;
429     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
430       return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
431       break;
432     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
433       return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
434       break;
435     case TLS_ECDH_RSA_WITH_NULL_SHA:
436       return "TLS_ECDH_RSA_WITH_NULL_SHA";
437       break;
438     case TLS_ECDH_RSA_WITH_RC4_128_SHA:
439       return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
440       break;
441     case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
442       return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
443       break;
444     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
445       return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
446       break;
447     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
448       return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
449       break;
450     case TLS_ECDHE_RSA_WITH_NULL_SHA:
451       return "TLS_ECDHE_RSA_WITH_NULL_SHA";
452       break;
453     case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
454       return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
455       break;
456     case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
457       return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
458       break;
459     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
460       return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
461       break;
462     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
463       return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
464       break;
465     case TLS_ECDH_anon_WITH_NULL_SHA:
466       return "TLS_ECDH_anon_WITH_NULL_SHA";
467       break;
468     case TLS_ECDH_anon_WITH_RC4_128_SHA:
469       return "TLS_ECDH_anon_WITH_RC4_128_SHA";
470       break;
471     case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
472       return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
473       break;
474     case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
475       return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
476       break;
477     case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
478       return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
479       break;
480 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
481 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
482     /* TLS 1.2 (RFC 5246) */
483     case TLS_RSA_WITH_NULL_MD5:
484       return "TLS_RSA_WITH_NULL_MD5";
485       break;
486     case TLS_RSA_WITH_NULL_SHA:
487       return "TLS_RSA_WITH_NULL_SHA";
488       break;
489     case TLS_RSA_WITH_RC4_128_MD5:
490       return "TLS_RSA_WITH_RC4_128_MD5";
491       break;
492     case TLS_RSA_WITH_RC4_128_SHA:
493       return "TLS_RSA_WITH_RC4_128_SHA";
494       break;
495     case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
496       return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
497       break;
498     case TLS_RSA_WITH_NULL_SHA256:
499       return "TLS_RSA_WITH_NULL_SHA256";
500       break;
501     case TLS_RSA_WITH_AES_128_CBC_SHA256:
502       return "TLS_RSA_WITH_AES_128_CBC_SHA256";
503       break;
504     case TLS_RSA_WITH_AES_256_CBC_SHA256:
505       return "TLS_RSA_WITH_AES_256_CBC_SHA256";
506       break;
507     case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
508       return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
509       break;
510     case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
511       return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
512       break;
513     case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
514       return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
515       break;
516     case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
517       return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
518       break;
519     case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
520       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
521       break;
522     case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
523       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
524       break;
525     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
526       return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
527       break;
528     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
529       return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
530       break;
531     case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
532       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
533       break;
534     case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
535       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
536       break;
537     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
538       return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
539       break;
540     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
541       return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
542       break;
543     case TLS_DH_anon_WITH_RC4_128_MD5:
544       return "TLS_DH_anon_WITH_RC4_128_MD5";
545       break;
546     case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
547       return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
548       break;
549     case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
550       return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
551       break;
552     case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
553       return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
554       break;
555     /* TLS 1.2 with AES GCM (RFC 5288) */
556     case TLS_RSA_WITH_AES_128_GCM_SHA256:
557       return "TLS_RSA_WITH_AES_128_GCM_SHA256";
558       break;
559     case TLS_RSA_WITH_AES_256_GCM_SHA384:
560       return "TLS_RSA_WITH_AES_256_GCM_SHA384";
561       break;
562     case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
563       return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
564       break;
565     case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
566       return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
567       break;
568     case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
569       return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
570       break;
571     case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
572       return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
573       break;
574     case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
575       return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
576       break;
577     case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
578       return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
579       break;
580     case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
581       return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
582       break;
583     case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
584       return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
585       break;
586     case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
587       return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
588       break;
589     case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
590       return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
591       break;
592     /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
593     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
594       return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
595       break;
596     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
597       return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
598       break;
599     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
600       return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
601       break;
602     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
603       return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
604       break;
605     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
606       return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
607       break;
608     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
609       return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
610       break;
611     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
612       return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
613       break;
614     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
615       return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
616       break;
617     case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
618       return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
619       break;
620     case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
621       return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
622       break;
623     case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
624       return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
625       break;
626     case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
627       return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
628       break;
629     case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
630       return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
631       break;
632     case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
633       return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
634       break;
635     case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
636       return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
637       break;
638     case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
639       return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
640       break;
641     case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
642       return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
643       break;
644 #else
645     case SSL_RSA_WITH_NULL_MD5:
646       return "TLS_RSA_WITH_NULL_MD5";
647       break;
648     case SSL_RSA_WITH_NULL_SHA:
649       return "TLS_RSA_WITH_NULL_SHA";
650       break;
651     case SSL_RSA_WITH_RC4_128_MD5:
652       return "TLS_RSA_WITH_RC4_128_MD5";
653       break;
654     case SSL_RSA_WITH_RC4_128_SHA:
655       return "TLS_RSA_WITH_RC4_128_SHA";
656       break;
657     case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
658       return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
659       break;
660     case SSL_DH_anon_WITH_RC4_128_MD5:
661       return "TLS_DH_anon_WITH_RC4_128_MD5";
662       break;
663     case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
664       return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
665       break;
666 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
667 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
668     /* TLS PSK (RFC 4279): */
669     case TLS_PSK_WITH_RC4_128_SHA:
670       return "TLS_PSK_WITH_RC4_128_SHA";
671       break;
672     case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
673       return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
674       break;
675     case TLS_PSK_WITH_AES_128_CBC_SHA:
676       return "TLS_PSK_WITH_AES_128_CBC_SHA";
677       break;
678     case TLS_PSK_WITH_AES_256_CBC_SHA:
679       return "TLS_PSK_WITH_AES_256_CBC_SHA";
680       break;
681     case TLS_DHE_PSK_WITH_RC4_128_SHA:
682       return "TLS_DHE_PSK_WITH_RC4_128_SHA";
683       break;
684     case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
685       return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
686       break;
687     case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
688       return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
689       break;
690     case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
691       return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
692       break;
693     case TLS_RSA_PSK_WITH_RC4_128_SHA:
694       return "TLS_RSA_PSK_WITH_RC4_128_SHA";
695       break;
696     case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
697       return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
698       break;
699     case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
700       return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
701       break;
702     case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
703       return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
704       break;
705     /* More TLS PSK (RFC 4785): */
706     case TLS_PSK_WITH_NULL_SHA:
707       return "TLS_PSK_WITH_NULL_SHA";
708       break;
709     case TLS_DHE_PSK_WITH_NULL_SHA:
710       return "TLS_DHE_PSK_WITH_NULL_SHA";
711       break;
712     case TLS_RSA_PSK_WITH_NULL_SHA:
713       return "TLS_RSA_PSK_WITH_NULL_SHA";
714       break;
715     /* Even more TLS PSK (RFC 5487): */
716     case TLS_PSK_WITH_AES_128_GCM_SHA256:
717       return "TLS_PSK_WITH_AES_128_GCM_SHA256";
718       break;
719     case TLS_PSK_WITH_AES_256_GCM_SHA384:
720       return "TLS_PSK_WITH_AES_256_GCM_SHA384";
721       break;
722     case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
723       return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
724       break;
725     case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
726       return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
727       break;
728     case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
729       return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
730       break;
731     case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
732       return "TLS_PSK_WITH_AES_256_GCM_SHA384";
733       break;
734     case TLS_PSK_WITH_AES_128_CBC_SHA256:
735       return "TLS_PSK_WITH_AES_128_CBC_SHA256";
736       break;
737     case TLS_PSK_WITH_AES_256_CBC_SHA384:
738       return "TLS_PSK_WITH_AES_256_CBC_SHA384";
739       break;
740     case TLS_PSK_WITH_NULL_SHA256:
741       return "TLS_PSK_WITH_NULL_SHA256";
742       break;
743     case TLS_PSK_WITH_NULL_SHA384:
744       return "TLS_PSK_WITH_NULL_SHA384";
745       break;
746     case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
747       return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
748       break;
749     case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
750       return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
751       break;
752     case TLS_DHE_PSK_WITH_NULL_SHA256:
753       return "TLS_DHE_PSK_WITH_NULL_SHA256";
754       break;
755     case TLS_DHE_PSK_WITH_NULL_SHA384:
756       return "TLS_RSA_PSK_WITH_NULL_SHA384";
757       break;
758     case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
759       return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
760       break;
761     case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
762       return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
763       break;
764     case TLS_RSA_PSK_WITH_NULL_SHA256:
765       return "TLS_RSA_PSK_WITH_NULL_SHA256";
766       break;
767     case TLS_RSA_PSK_WITH_NULL_SHA384:
768       return "TLS_RSA_PSK_WITH_NULL_SHA384";
769       break;
770 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
771   }
772   return "TLS_NULL_WITH_NULL_NULL";
773 }
774
775 #if CURL_BUILD_MAC
776 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
777 {
778   int mib[2];
779   char *os_version;
780   size_t os_version_len;
781   char *os_version_major, *os_version_minor/*, *os_version_point*/;
782
783   /* Get the Darwin kernel version from the kernel using sysctl(): */
784   mib[0] = CTL_KERN;
785   mib[1] = KERN_OSRELEASE;
786   if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
787     return;
788   os_version = malloc(os_version_len*sizeof(char));
789   if(!os_version)
790     return;
791   if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
792     free(os_version);
793     return;
794   }
795
796   /* Parse the version: */
797   os_version_major = strtok(os_version, ".");
798   os_version_minor = strtok(NULL, ".");
799   /*os_version_point = strtok(NULL, ".");*/
800   *major = atoi(os_version_major);
801   *minor = atoi(os_version_minor);
802   free(os_version);
803 }
804 #endif /* CURL_BUILD_MAC */
805
806 /* Apple provides a myriad of ways of getting information about a certificate
807    into a string. Some aren't available under iOS or newer cats. So here's
808    a unified function for getting a string describing the certificate that
809    ought to work in all cats starting with Leopard. */
810 CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
811 {
812   CFStringRef server_cert_summary = CFSTR("(null)");
813
814 #if CURL_BUILD_IOS
815   /* iOS: There's only one way to do this. */
816   server_cert_summary = SecCertificateCopySubjectSummary(cert);
817 #else
818 #if CURL_BUILD_MAC_10_7
819   /* Lion & later: Get the long description if we can. */
820   if(SecCertificateCopyLongDescription != NULL)
821     server_cert_summary =
822       SecCertificateCopyLongDescription(NULL, cert, NULL);
823   else
824 #endif /* CURL_BUILD_MAC_10_7 */
825 #if CURL_BUILD_MAC_10_6
826   /* Snow Leopard: Get the certificate summary. */
827   if(SecCertificateCopySubjectSummary != NULL)
828     server_cert_summary = SecCertificateCopySubjectSummary(cert);
829   else
830 #endif /* CURL_BUILD_MAC_10_6 */
831   /* Leopard is as far back as we go... */
832   (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
833 #endif /* CURL_BUILD_IOS */
834   return server_cert_summary;
835 }
836
837 #if CURL_SUPPORT_MAC_10_6
838 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
839    deprecation warnings, so let's not compile this unless it's necessary: */
840 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
841                                                SecIdentityRef *out_c_a_k)
842 {
843   OSStatus status = errSecItemNotFound;
844   SecKeychainAttributeList attr_list;
845   SecKeychainAttribute attr;
846   SecKeychainSearchRef search = NULL;
847   SecCertificateRef cert = NULL;
848
849   /* Set up the attribute list: */
850   attr_list.count = 1L;
851   attr_list.attr = &attr;
852
853   /* Set up our lone search criterion: */
854   attr.tag = kSecLabelItemAttr;
855   attr.data = label;
856   attr.length = (UInt32)strlen(label);
857
858   /* Start searching: */
859   status = SecKeychainSearchCreateFromAttributes(NULL,
860                                                  kSecCertificateItemClass,
861                                                  &attr_list,
862                                                  &search);
863   if(status == noErr) {
864     status = SecKeychainSearchCopyNext(search,
865                                        (SecKeychainItemRef *)&cert);
866     if(status == noErr && cert) {
867       /* If we found a certificate, does it have a private key? */
868       status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
869       CFRelease(cert);
870     }
871   }
872
873   if(search)
874     CFRelease(search);
875   return status;
876 }
877 #endif /* CURL_SUPPORT_MAC_10_6 */
878
879 static OSStatus CopyIdentityWithLabel(char *label,
880                                       SecIdentityRef *out_cert_and_key)
881 {
882   OSStatus status = errSecItemNotFound;
883
884 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
885   /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
886      kSecClassIdentity was introduced in Lion. If both exist, let's use them
887      to find the certificate. */
888   if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
889     CFTypeRef keys[4];
890     CFTypeRef values[4];
891     CFDictionaryRef query_dict;
892     CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
893       kCFStringEncodingUTF8);
894
895     /* Set up our search criteria and expected results: */
896     values[0] = kSecClassIdentity; /* we want a certificate and a key */
897     keys[0] = kSecClass;
898     values[1] = kCFBooleanTrue;    /* we want a reference */
899     keys[1] = kSecReturnRef;
900     values[2] = kSecMatchLimitOne; /* one is enough, thanks */
901     keys[2] = kSecMatchLimit;
902     /* identity searches need a SecPolicyRef in order to work */
903     values[3] = SecPolicyCreateSSL(false, label_cf);
904     keys[3] = kSecMatchPolicy;
905     query_dict = CFDictionaryCreate(NULL, (const void **)keys,
906                                    (const void **)values, 4L,
907                                    &kCFCopyStringDictionaryKeyCallBacks,
908                                    &kCFTypeDictionaryValueCallBacks);
909     CFRelease(values[3]);
910     CFRelease(label_cf);
911
912     /* Do we have a match? */
913     status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
914     CFRelease(query_dict);
915   }
916   else {
917 #if CURL_SUPPORT_MAC_10_6
918     /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
919     status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
920 #endif /* CURL_SUPPORT_MAC_10_7 */
921   }
922 #elif CURL_SUPPORT_MAC_10_6
923   /* For developers building on older cats, we have no choice but to fall back
924      to SecKeychainSearch. */
925   status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
926 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
927   return status;
928 }
929
930 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
931                                            const char *cPassword,
932                                            SecIdentityRef *out_cert_and_key)
933 {
934   OSStatus status = errSecItemNotFound;
935   CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
936     (const UInt8 *)cPath, strlen(cPath), false);
937   CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
938     cPassword, kCFStringEncodingUTF8) : NULL;
939   CFDataRef pkcs_data = NULL;
940
941   /* We can import P12 files on iOS or OS X 10.7 or later: */
942   /* These constants are documented as having first appeared in 10.6 but they
943      raise linker errors when used on that cat for some reason. */
944 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
945   if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
946     NULL, NULL, &status)) {
947     const void *cKeys[] = {kSecImportExportPassphrase};
948     const void *cValues[] = {password};
949     CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
950       password ? 1L : 0L, NULL, NULL);
951     CFArrayRef items = NULL;
952
953     /* Here we go: */
954     status = SecPKCS12Import(pkcs_data, options, &items);
955     if(status == noErr && items && CFArrayGetCount(items)) {
956       CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
957       const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
958         kSecImportItemIdentity);
959
960       /* Retain the identity; we don't care about any other data... */
961       CFRetain(temp_identity);
962       *out_cert_and_key = (SecIdentityRef)temp_identity;
963     }
964
965     if(items)
966       CFRelease(items);
967     CFRelease(options);
968     CFRelease(pkcs_data);
969   }
970 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
971   if(password)
972     CFRelease(password);
973   CFRelease(pkcs_url);
974   return status;
975 }
976
977 /* This code was borrowed from nss.c, with some modifications:
978  * Determine whether the nickname passed in is a filename that needs to
979  * be loaded as a PEM or a regular NSS nickname.
980  *
981  * returns 1 for a file
982  * returns 0 for not a file
983  */
984 CF_INLINE bool is_file(const char *filename)
985 {
986   struct_stat st;
987
988   if(filename == NULL)
989     return false;
990
991   if(stat(filename, &st) == 0)
992     return S_ISREG(st.st_mode);
993   return false;
994 }
995
996 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
997                                         int sockindex)
998 {
999   struct SessionHandle *data = conn->data;
1000   curl_socket_t sockfd = conn->sock[sockindex];
1001   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1002 #ifdef ENABLE_IPV6
1003   struct in6_addr addr;
1004 #else
1005   struct in_addr addr;
1006 #endif /* ENABLE_IPV6 */
1007   size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1008   SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1009   char *ssl_sessionid;
1010   size_t ssl_sessionid_len;
1011   OSStatus err = noErr;
1012 #if CURL_BUILD_MAC
1013   int darwinver_maj = 0, darwinver_min = 0;
1014
1015   GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1016 #endif /* CURL_BUILD_MAC */
1017
1018 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1019   if(SSLCreateContext != NULL) {  /* use the newer API if avaialble */
1020     if(connssl->ssl_ctx)
1021       CFRelease(connssl->ssl_ctx);
1022     connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1023     if(!connssl->ssl_ctx) {
1024       failf(data, "SSL: couldn't create a context!");
1025       return CURLE_OUT_OF_MEMORY;
1026     }
1027   }
1028   else {
1029   /* The old ST API does not exist under iOS, so don't compile it: */
1030 #if CURL_SUPPORT_MAC_10_8
1031     if(connssl->ssl_ctx)
1032       (void)SSLDisposeContext(connssl->ssl_ctx);
1033     err = SSLNewContext(false, &(connssl->ssl_ctx));
1034     if(err != noErr) {
1035       failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1036       return CURLE_OUT_OF_MEMORY;
1037     }
1038 #endif /* CURL_SUPPORT_MAC_10_8 */
1039   }
1040 #else
1041   if(connssl->ssl_ctx)
1042     (void)SSLDisposeContext(connssl->ssl_ctx);
1043   err = SSLNewContext(false, &(connssl->ssl_ctx));
1044   if(err != noErr) {
1045     failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1046     return CURLE_OUT_OF_MEMORY;
1047   }
1048 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1049   connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1050
1051   /* check to see if we've been told to use an explicit SSL/TLS version */
1052 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1053   if(SSLSetProtocolVersionMax != NULL) {
1054     switch(data->set.ssl.version) {
1055       case CURL_SSLVERSION_DEFAULT: default:
1056         (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1057         (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1058         break;
1059       case CURL_SSLVERSION_TLSv1:
1060         (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1061         (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1062         break;
1063       case CURL_SSLVERSION_TLSv1_0:
1064         (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1065         (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
1066         break;
1067       case CURL_SSLVERSION_TLSv1_1:
1068         (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
1069         (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
1070         break;
1071       case CURL_SSLVERSION_TLSv1_2:
1072         (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
1073         (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1074         break;
1075       case CURL_SSLVERSION_SSLv3:
1076         (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1077         (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
1078         break;
1079       case CURL_SSLVERSION_SSLv2:
1080         err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
1081         if(err != noErr) {
1082           failf(data, "Your version of the OS does not support SSLv2");
1083           return CURLE_SSL_CONNECT_ERROR;
1084         }
1085         (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
1086     }
1087   }
1088   else {
1089 #if CURL_SUPPORT_MAC_10_8
1090     (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1091                                        kSSLProtocolAll,
1092                                        false);
1093     switch (data->set.ssl.version) {
1094       case CURL_SSLVERSION_DEFAULT: default:
1095         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1096                                            kSSLProtocol3,
1097                                            true);
1098         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1099                                            kTLSProtocol1,
1100                                            true);
1101         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1102                                            kTLSProtocol11,
1103                                            true);
1104         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1105                                            kTLSProtocol12,
1106                                            true);
1107         break;
1108       case CURL_SSLVERSION_TLSv1:
1109         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1110                                            kTLSProtocol1,
1111                                            true);
1112         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1113                                            kTLSProtocol11,
1114                                            true);
1115         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1116                                            kTLSProtocol12,
1117                                            true);
1118         break;
1119       case CURL_SSLVERSION_TLSv1_0:
1120         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1121                                            kTLSProtocol1,
1122                                            true);
1123         break;
1124       case CURL_SSLVERSION_TLSv1_1:
1125         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1126                                            kTLSProtocol11,
1127                                            true);
1128         break;
1129       case CURL_SSLVERSION_TLSv1_2:
1130         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1131                                            kTLSProtocol12,
1132                                            true);
1133         break;
1134       case CURL_SSLVERSION_SSLv3:
1135         (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1136                                            kSSLProtocol3,
1137                                            true);
1138         break;
1139       case CURL_SSLVERSION_SSLv2:
1140         err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1141                                            kSSLProtocol2,
1142                                            true);
1143         if(err != noErr) {
1144           failf(data, "Your version of the OS does not support SSLv2");
1145           return CURLE_SSL_CONNECT_ERROR;
1146         }
1147         break;
1148     }
1149 #endif  /* CURL_SUPPORT_MAC_10_8 */
1150   }
1151 #else
1152   (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
1153   switch(data->set.ssl.version) {
1154     default:
1155     case CURL_SSLVERSION_DEFAULT:
1156       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1157                                          kSSLProtocol3,
1158                                          true);
1159       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1160                                          kTLSProtocol1,
1161                                          true);
1162       break;
1163     case CURL_SSLVERSION_TLSv1:
1164     case CURL_SSLVERSION_TLSv1_0:
1165       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1166                                          kTLSProtocol1,
1167                                          true);
1168       break;
1169     case CURL_SSLVERSION_TLSv1_1:
1170       failf(data, "Your version of the OS does not support TLSv1.1");
1171       return CURLE_SSL_CONNECT_ERROR;
1172     case CURL_SSLVERSION_TLSv1_2:
1173       failf(data, "Your version of the OS does not support TLSv1.2");
1174       return CURLE_SSL_CONNECT_ERROR;
1175     case CURL_SSLVERSION_SSLv2:
1176       err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1177                                          kSSLProtocol2,
1178                                          true);
1179       if(err != noErr) {
1180         failf(data, "Your version of the OS does not support SSLv2");
1181         return CURLE_SSL_CONNECT_ERROR;
1182       }
1183       break;
1184     case CURL_SSLVERSION_SSLv3:
1185       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1186                                          kSSLProtocol3,
1187                                          true);
1188       break;
1189   }
1190 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1191
1192   if(data->set.str[STRING_KEY]) {
1193     infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1194                 "Transport. The private key must be in the Keychain.\n");
1195   }
1196
1197   if(data->set.str[STRING_CERT]) {
1198     SecIdentityRef cert_and_key = NULL;
1199     bool is_cert_file = is_file(data->set.str[STRING_CERT]);
1200
1201     /* User wants to authenticate with a client cert. Look for it:
1202        If we detect that this is a file on disk, then let's load it.
1203        Otherwise, assume that the user wants to use an identity loaded
1204        from the Keychain. */
1205     if(is_cert_file) {
1206       if(!data->set.str[STRING_CERT_TYPE])
1207         infof(data, "WARNING: SSL: Certificate type not set, assuming "
1208                     "PKCS#12 format.\n");
1209       else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
1210         strlen(data->set.str[STRING_CERT_TYPE])) != 0)
1211         infof(data, "WARNING: SSL: The Security framework only supports "
1212                     "loading identities that are in PKCS#12 format.\n");
1213
1214       err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
1215         data->set.str[STRING_KEY_PASSWD], &cert_and_key);
1216     }
1217     else
1218       err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
1219
1220     if(err == noErr) {
1221       SecCertificateRef cert = NULL;
1222       CFTypeRef certs_c[1];
1223       CFArrayRef certs;
1224
1225       /* If we found one, print it out: */
1226       err = SecIdentityCopyCertificate(cert_and_key, &cert);
1227       if(err == noErr) {
1228         CFStringRef cert_summary = CopyCertSubject(cert);
1229         char cert_summary_c[128];
1230
1231         if(cert_summary) {
1232           memset(cert_summary_c, 0, 128);
1233           if(CFStringGetCString(cert_summary,
1234                                 cert_summary_c,
1235                                 128,
1236                                 kCFStringEncodingUTF8)) {
1237             infof(data, "Client certificate: %s\n", cert_summary_c);
1238           }
1239           CFRelease(cert_summary);
1240           CFRelease(cert);
1241         }
1242       }
1243       certs_c[0] = cert_and_key;
1244       certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1245                             &kCFTypeArrayCallBacks);
1246       err = SSLSetCertificate(connssl->ssl_ctx, certs);
1247       if(certs)
1248         CFRelease(certs);
1249       if(err != noErr) {
1250         failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1251         return CURLE_SSL_CERTPROBLEM;
1252       }
1253       CFRelease(cert_and_key);
1254     }
1255     else {
1256       switch(err) {
1257         case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1258           failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1259                       "and its private key.", data->set.str[STRING_CERT]);
1260           break;
1261         case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1262           failf(data, "SSL: Couldn't make sense of the data in the "
1263                       "certificate \"%s\" and its private key.",
1264                       data->set.str[STRING_CERT]);
1265           break;
1266         case -25260: /* errSecPassphraseRequired */
1267           failf(data, "SSL The certificate \"%s\" requires a password.",
1268                       data->set.str[STRING_CERT]);
1269           break;
1270         case errSecItemNotFound:
1271           failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1272                       "key in the Keychain.", data->set.str[STRING_CERT]);
1273           break;
1274         default:
1275           failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1276                       "key: OSStatus %d", data->set.str[STRING_CERT], err);
1277           break;
1278       }
1279       return CURLE_SSL_CERTPROBLEM;
1280     }
1281   }
1282
1283   /* SSL always tries to verify the peer, this only says whether it should
1284    * fail to connect if the verification fails, or if it should continue
1285    * anyway. In the latter case the result of the verification is checked with
1286    * SSL_get_verify_result() below. */
1287 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1288   /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1289      a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1290      works, it doesn't work as expected under Snow Leopard or Lion.
1291      So we need to call SSLSetEnableCertVerify() on those older cats in order
1292      to disable certificate validation if the user turned that off.
1293      (SecureTransport will always validate the certificate chain by
1294      default.) */
1295   /* (Note: Darwin 12.x.x is Mountain Lion.) */
1296 #if CURL_BUILD_MAC
1297   if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
1298 #else
1299   if(SSLSetSessionOption != NULL) {
1300 #endif /* CURL_BUILD_MAC */
1301     err = SSLSetSessionOption(connssl->ssl_ctx,
1302                               kSSLSessionOptionBreakOnServerAuth,
1303                               data->set.ssl.verifypeer?false:true);
1304     if(err != noErr) {
1305       failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1306       return CURLE_SSL_CONNECT_ERROR;
1307     }
1308   }
1309   else {
1310 #if CURL_SUPPORT_MAC_10_8
1311     err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1312                                  data->set.ssl.verifypeer?true:false);
1313     if(err != noErr) {
1314       failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1315       return CURLE_SSL_CONNECT_ERROR;
1316     }
1317 #endif /* CURL_SUPPORT_MAC_10_8 */
1318   }
1319 #else
1320   err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1321                                data->set.ssl.verifypeer?true:false);
1322   if(err != noErr) {
1323     failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1324     return CURLE_SSL_CONNECT_ERROR;
1325   }
1326 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1327
1328   /* Configure hostname check. SNI is used if available.
1329    * Both hostname check and SNI require SSLSetPeerDomainName().
1330    * Also: the verifyhost setting influences SNI usage */
1331   if(data->set.ssl.verifyhost) {
1332     err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1333     strlen(conn->host.name));
1334
1335     if(err != noErr) {
1336       infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1337             err);
1338     }
1339
1340     if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
1341   #ifdef ENABLE_IPV6
1342     || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
1343   #endif
1344        ) {
1345          infof(data, "WARNING: using IP address, SNI is being disabled by "
1346          "the OS.\n");
1347     }
1348   }
1349
1350   /* Disable cipher suites that ST supports but are not safe. These ciphers
1351      are unlikely to be used in any case since ST gives other ciphers a much
1352      higher priority, but it's probably better that we not connect at all than
1353      to give the user a false sense of security if the server only supports
1354      insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1355   (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1356   all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1357   allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1358   if(all_ciphers && allowed_ciphers &&
1359      SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1360        &all_ciphers_count) == noErr) {
1361     for(i = 0UL ; i < all_ciphers_count ; i++) {
1362 #if CURL_BUILD_MAC
1363      /* There's a known bug in early versions of Mountain Lion where ST's ECC
1364         ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1365         Work around the problem here by disabling those ciphers if we are
1366         running in an affected version of OS X. */
1367       if(darwinver_maj == 12 && darwinver_min <= 3 &&
1368          all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1369            continue;
1370       }
1371 #endif /* CURL_BUILD_MAC */
1372       switch(all_ciphers[i]) {
1373         /* Disable NULL ciphersuites: */
1374         case SSL_NULL_WITH_NULL_NULL:
1375         case SSL_RSA_WITH_NULL_MD5:
1376         case SSL_RSA_WITH_NULL_SHA:
1377         case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1378         case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1379         case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1380         case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1381         case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1382         case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1383         case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1384         case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1385         case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1386         case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1387         case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1388         case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1389         case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1390         case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1391         case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1392         /* Disable anonymous ciphersuites: */
1393         case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1394         case SSL_DH_anon_WITH_RC4_128_MD5:
1395         case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1396         case SSL_DH_anon_WITH_DES_CBC_SHA:
1397         case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1398         case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1399         case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1400         case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1401         case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1402         case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1403         case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1404         case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1405         case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1406         case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1407         case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1408         case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1409         /* Disable weak key ciphersuites: */
1410         case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1411         case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1412         case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1413         case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1414         case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1415         case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1416         case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1417         case SSL_RSA_WITH_DES_CBC_SHA:
1418         case SSL_DH_DSS_WITH_DES_CBC_SHA:
1419         case SSL_DH_RSA_WITH_DES_CBC_SHA:
1420         case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1421         case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1422         /* Disable IDEA: */
1423         case SSL_RSA_WITH_IDEA_CBC_SHA:
1424         case SSL_RSA_WITH_IDEA_CBC_MD5:
1425           break;
1426         default: /* enable everything else */
1427           allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1428           break;
1429       }
1430     }
1431     err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1432                                allowed_ciphers_count);
1433     if(err != noErr) {
1434       failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1435       return CURLE_SSL_CONNECT_ERROR;
1436     }
1437   }
1438   else {
1439     Curl_safefree(all_ciphers);
1440     Curl_safefree(allowed_ciphers);
1441     failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1442     return CURLE_OUT_OF_MEMORY;
1443   }
1444   Curl_safefree(all_ciphers);
1445   Curl_safefree(allowed_ciphers);
1446
1447 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1448   /* We want to enable 1/n-1 when using a CBC cipher unless the user
1449      specifically doesn't want us doing that: */
1450   if(SSLSetSessionOption != NULL)
1451     SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1452                       !data->set.ssl_enable_beast);
1453 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1454
1455   /* Check if there's a cached ID we can/should use here! */
1456   if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1457     &ssl_sessionid_len)) {
1458     /* we got a session id, use it! */
1459     err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1460     if(err != noErr) {
1461       failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1462       return CURLE_SSL_CONNECT_ERROR;
1463     }
1464     /* Informational message */
1465     infof(data, "SSL re-using session ID\n");
1466   }
1467   /* If there isn't one, then let's make one up! This has to be done prior
1468      to starting the handshake. */
1469   else {
1470     CURLcode retcode;
1471
1472     ssl_sessionid = malloc(256*sizeof(char));
1473     ssl_sessionid_len = snprintf(ssl_sessionid, 256, "curl:%s:%hu",
1474       conn->host.name, conn->remote_port);
1475     err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1476     if(err != noErr) {
1477       failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1478       return CURLE_SSL_CONNECT_ERROR;
1479     }
1480     retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1481     if(retcode!= CURLE_OK) {
1482       failf(data, "failed to store ssl session");
1483       return retcode;
1484     }
1485   }
1486
1487   err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1488   if(err != noErr) {
1489     failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1490     return CURLE_SSL_CONNECT_ERROR;
1491   }
1492
1493   /* pass the raw socket into the SSL layers */
1494   /* We need to store the FD in a constant memory address, because
1495    * SSLSetConnection() will not copy that address. I've found that
1496    * conn->sock[sockindex] may change on its own. */
1497   connssl->ssl_sockfd = sockfd;
1498   err = SSLSetConnection(connssl->ssl_ctx, connssl);
1499   if(err != noErr) {
1500     failf(data, "SSL: SSLSetConnection() failed: %d", err);
1501     return CURLE_SSL_CONNECT_ERROR;
1502   }
1503
1504   connssl->connecting_state = ssl_connect_2;
1505   return CURLE_OK;
1506 }
1507
1508 static CURLcode
1509 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1510 {
1511   struct SessionHandle *data = conn->data;
1512   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1513   OSStatus err;
1514   SSLCipherSuite cipher;
1515   SSLProtocol protocol = 0;
1516
1517   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1518               || ssl_connect_2_reading == connssl->connecting_state
1519               || ssl_connect_2_writing == connssl->connecting_state);
1520
1521   /* Here goes nothing: */
1522   err = SSLHandshake(connssl->ssl_ctx);
1523
1524   if(err != noErr) {
1525     switch (err) {
1526       case errSSLWouldBlock:  /* they're not done with us yet */
1527         connssl->connecting_state = connssl->ssl_direction ?
1528             ssl_connect_2_writing : ssl_connect_2_reading;
1529         return CURLE_OK;
1530
1531       /* The below is errSSLServerAuthCompleted; it's not defined in
1532         Leopard's headers */
1533       case -9841:
1534         /* the documentation says we need to call SSLHandshake() again */
1535         return darwinssl_connect_step2(conn, sockindex);
1536
1537       /* These are all certificate problems with the server: */
1538       case errSSLXCertChainInvalid:
1539         failf(data, "SSL certificate problem: Invalid certificate chain");
1540         return CURLE_SSL_CACERT;
1541       case errSSLUnknownRootCert:
1542         failf(data, "SSL certificate problem: Untrusted root certificate");
1543         return CURLE_SSL_CACERT;
1544       case errSSLNoRootCert:
1545         failf(data, "SSL certificate problem: No root certificate");
1546         return CURLE_SSL_CACERT;
1547       case errSSLCertExpired:
1548         failf(data, "SSL certificate problem: Certificate chain had an "
1549               "expired certificate");
1550         return CURLE_SSL_CACERT;
1551       case errSSLBadCert:
1552         failf(data, "SSL certificate problem: Couldn't understand the server "
1553               "certificate format");
1554         return CURLE_SSL_CONNECT_ERROR;
1555
1556       /* These are all certificate problems with the client: */
1557       case errSecAuthFailed:
1558         failf(data, "SSL authentication failed");
1559         return CURLE_SSL_CONNECT_ERROR;
1560       case errSSLPeerHandshakeFail:
1561         failf(data, "SSL peer handshake failed, the server most likely "
1562               "requires a client certificate to connect");
1563         return CURLE_SSL_CONNECT_ERROR;
1564       case errSSLPeerUnknownCA:
1565         failf(data, "SSL server rejected the client certificate due to "
1566               "the certificate being signed by an unknown certificate "
1567               "authority");
1568         return CURLE_SSL_CONNECT_ERROR;
1569
1570       /* This error is raised if the server's cert didn't match the server's
1571          host name: */
1572       case errSSLHostNameMismatch:
1573         failf(data, "SSL certificate peer verification failed, the "
1574               "certificate did not match \"%s\"\n", conn->host.dispname);
1575         return CURLE_PEER_FAILED_VERIFICATION;
1576
1577       /* Generic handshake errors: */
1578       case errSSLConnectionRefused:
1579         failf(data, "Server dropped the connection during the SSL handshake");
1580         return CURLE_SSL_CONNECT_ERROR;
1581       case errSSLClosedAbort:
1582         failf(data, "Server aborted the SSL handshake");
1583         return CURLE_SSL_CONNECT_ERROR;
1584       case errSSLNegotiation:
1585         failf(data, "Could not negotiate an SSL cipher suite with the server");
1586         return CURLE_SSL_CONNECT_ERROR;
1587       /* Sometimes paramErr happens with buggy ciphers: */
1588       case paramErr: case errSSLInternal:
1589         failf(data, "Internal SSL engine error encountered during the "
1590               "SSL handshake");
1591         return CURLE_SSL_CONNECT_ERROR;
1592       case errSSLFatalAlert:
1593         failf(data, "Fatal SSL engine error encountered during the SSL "
1594               "handshake");
1595         return CURLE_SSL_CONNECT_ERROR;
1596       default:
1597         failf(data, "Unknown SSL protocol error in connection to %s:%d",
1598               conn->host.name, err);
1599         return CURLE_SSL_CONNECT_ERROR;
1600     }
1601   }
1602   else {
1603     /* we have been connected fine, we're not waiting for anything else. */
1604     connssl->connecting_state = ssl_connect_3;
1605
1606     /* Informational message */
1607     (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1608     (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1609     switch (protocol) {
1610       case kSSLProtocol2:
1611         infof(data, "SSL 2.0 connection using %s\n",
1612               SSLCipherNameForNumber(cipher));
1613         break;
1614       case kSSLProtocol3:
1615         infof(data, "SSL 3.0 connection using %s\n",
1616               SSLCipherNameForNumber(cipher));
1617         break;
1618       case kTLSProtocol1:
1619         infof(data, "TLS 1.0 connection using %s\n",
1620               TLSCipherNameForNumber(cipher));
1621         break;
1622 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1623       case kTLSProtocol11:
1624         infof(data, "TLS 1.1 connection using %s\n",
1625               TLSCipherNameForNumber(cipher));
1626         break;
1627       case kTLSProtocol12:
1628         infof(data, "TLS 1.2 connection using %s\n",
1629               TLSCipherNameForNumber(cipher));
1630         break;
1631 #endif
1632       default:
1633         infof(data, "Unknown protocol connection\n");
1634         break;
1635     }
1636
1637     return CURLE_OK;
1638   }
1639 }
1640
1641 static CURLcode
1642 darwinssl_connect_step3(struct connectdata *conn,
1643                         int sockindex)
1644 {
1645   struct SessionHandle *data = conn->data;
1646   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1647   CFStringRef server_cert_summary;
1648   char server_cert_summary_c[128];
1649   CFArrayRef server_certs = NULL;
1650   SecCertificateRef server_cert;
1651   OSStatus err;
1652   CFIndex i, count;
1653   SecTrustRef trust = NULL;
1654
1655   /* There is no step 3!
1656    * Well, okay, if verbose mode is on, let's print the details of the
1657    * server certificates. */
1658 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1659 #if CURL_BUILD_IOS
1660 #pragma unused(server_certs)
1661   err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1662   /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1663      a null trust, so be on guard for that: */
1664   if(err == noErr && trust) {
1665     count = SecTrustGetCertificateCount(trust);
1666     for(i = 0L ; i < count ; i++) {
1667       server_cert = SecTrustGetCertificateAtIndex(trust, i);
1668       server_cert_summary = CopyCertSubject(server_cert);
1669       memset(server_cert_summary_c, 0, 128);
1670       if(CFStringGetCString(server_cert_summary,
1671                             server_cert_summary_c,
1672                             128,
1673                             kCFStringEncodingUTF8)) {
1674         infof(data, "Server certificate: %s\n", server_cert_summary_c);
1675       }
1676       CFRelease(server_cert_summary);
1677     }
1678     CFRelease(trust);
1679   }
1680 #else
1681   /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
1682      The function SecTrustGetCertificateAtIndex() is officially present
1683      in Lion, but it is unfortunately also present in Snow Leopard as
1684      private API and doesn't work as expected. So we have to look for
1685      a different symbol to make sure this code is only executed under
1686      Lion or later. */
1687   if(SecTrustEvaluateAsync != NULL) {
1688 #pragma unused(server_certs)
1689     err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1690     /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1691        a null trust, so be on guard for that: */
1692     if(err == noErr && trust) {
1693       count = SecTrustGetCertificateCount(trust);
1694       for(i = 0L ; i < count ; i++) {
1695         server_cert = SecTrustGetCertificateAtIndex(trust, i);
1696         server_cert_summary = CopyCertSubject(server_cert);
1697         memset(server_cert_summary_c, 0, 128);
1698         if(CFStringGetCString(server_cert_summary,
1699                               server_cert_summary_c,
1700                               128,
1701                               kCFStringEncodingUTF8)) {
1702           infof(data, "Server certificate: %s\n", server_cert_summary_c);
1703         }
1704         CFRelease(server_cert_summary);
1705       }
1706       CFRelease(trust);
1707     }
1708   }
1709   else {
1710 #if CURL_SUPPORT_MAC_10_8
1711     err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1712     /* Just in case SSLCopyPeerCertificates() returns null too... */
1713     if(err == noErr && server_certs) {
1714       count = CFArrayGetCount(server_certs);
1715       for(i = 0L ; i < count ; i++) {
1716         server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
1717                                                                 i);
1718
1719         server_cert_summary = CopyCertSubject(server_cert);
1720         memset(server_cert_summary_c, 0, 128);
1721         if(CFStringGetCString(server_cert_summary,
1722                               server_cert_summary_c,
1723                               128,
1724                               kCFStringEncodingUTF8)) {
1725           infof(data, "Server certificate: %s\n", server_cert_summary_c);
1726         }
1727         CFRelease(server_cert_summary);
1728       }
1729       CFRelease(server_certs);
1730     }
1731 #endif /* CURL_SUPPORT_MAC_10_8 */
1732   }
1733 #endif /* CURL_BUILD_IOS */
1734 #else
1735 #pragma unused(trust)
1736   err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1737   if(err == noErr) {
1738     count = CFArrayGetCount(server_certs);
1739     for(i = 0L ; i < count ; i++) {
1740       server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
1741       server_cert_summary = CopyCertSubject(server_cert);
1742       memset(server_cert_summary_c, 0, 128);
1743       if(CFStringGetCString(server_cert_summary,
1744                             server_cert_summary_c,
1745                             128,
1746                             kCFStringEncodingUTF8)) {
1747         infof(data, "Server certificate: %s\n", server_cert_summary_c);
1748       }
1749       CFRelease(server_cert_summary);
1750     }
1751     CFRelease(server_certs);
1752   }
1753 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1754
1755   connssl->connecting_state = ssl_connect_done;
1756   return CURLE_OK;
1757 }
1758
1759 static Curl_recv darwinssl_recv;
1760 static Curl_send darwinssl_send;
1761
1762 static CURLcode
1763 darwinssl_connect_common(struct connectdata *conn,
1764                          int sockindex,
1765                          bool nonblocking,
1766                          bool *done)
1767 {
1768   CURLcode retcode;
1769   struct SessionHandle *data = conn->data;
1770   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1771   curl_socket_t sockfd = conn->sock[sockindex];
1772   long timeout_ms;
1773   int what;
1774
1775   /* check if the connection has already been established */
1776   if(ssl_connection_complete == connssl->state) {
1777     *done = TRUE;
1778     return CURLE_OK;
1779   }
1780
1781   if(ssl_connect_1==connssl->connecting_state) {
1782     /* Find out how much more time we're allowed */
1783     timeout_ms = Curl_timeleft(data, NULL, TRUE);
1784
1785     if(timeout_ms < 0) {
1786       /* no need to continue if time already is up */
1787       failf(data, "SSL connection timeout");
1788       return CURLE_OPERATION_TIMEDOUT;
1789     }
1790     retcode = darwinssl_connect_step1(conn, sockindex);
1791     if(retcode)
1792       return retcode;
1793   }
1794
1795   while(ssl_connect_2 == connssl->connecting_state ||
1796         ssl_connect_2_reading == connssl->connecting_state ||
1797         ssl_connect_2_writing == connssl->connecting_state) {
1798
1799     /* check allowed time left */
1800     timeout_ms = Curl_timeleft(data, NULL, TRUE);
1801
1802     if(timeout_ms < 0) {
1803       /* no need to continue if time already is up */
1804       failf(data, "SSL connection timeout");
1805       return CURLE_OPERATION_TIMEDOUT;
1806     }
1807
1808     /* if ssl is expecting something, check if it's available. */
1809     if(connssl->connecting_state == ssl_connect_2_reading
1810        || connssl->connecting_state == ssl_connect_2_writing) {
1811
1812       curl_socket_t writefd = ssl_connect_2_writing ==
1813       connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1814       curl_socket_t readfd = ssl_connect_2_reading ==
1815       connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1816
1817       what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
1818       if(what < 0) {
1819         /* fatal error */
1820         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1821         return CURLE_SSL_CONNECT_ERROR;
1822       }
1823       else if(0 == what) {
1824         if(nonblocking) {
1825           *done = FALSE;
1826           return CURLE_OK;
1827         }
1828         else {
1829           /* timeout */
1830           failf(data, "SSL connection timeout");
1831           return CURLE_OPERATION_TIMEDOUT;
1832         }
1833       }
1834       /* socket is readable or writable */
1835     }
1836
1837     /* Run transaction, and return to the caller if it failed or if this
1838      * connection is done nonblocking and this loop would execute again. This
1839      * permits the owner of a multi handle to abort a connection attempt
1840      * before step2 has completed while ensuring that a client using select()
1841      * or epoll() will always have a valid fdset to wait on.
1842      */
1843     retcode = darwinssl_connect_step2(conn, sockindex);
1844     if(retcode || (nonblocking &&
1845                    (ssl_connect_2 == connssl->connecting_state ||
1846                     ssl_connect_2_reading == connssl->connecting_state ||
1847                     ssl_connect_2_writing == connssl->connecting_state)))
1848       return retcode;
1849
1850   } /* repeat step2 until all transactions are done. */
1851
1852
1853   if(ssl_connect_3==connssl->connecting_state) {
1854     retcode = darwinssl_connect_step3(conn, sockindex);
1855     if(retcode)
1856       return retcode;
1857   }
1858
1859   if(ssl_connect_done==connssl->connecting_state) {
1860     connssl->state = ssl_connection_complete;
1861     conn->recv[sockindex] = darwinssl_recv;
1862     conn->send[sockindex] = darwinssl_send;
1863     *done = TRUE;
1864   }
1865   else
1866     *done = FALSE;
1867
1868   /* Reset our connect state machine */
1869   connssl->connecting_state = ssl_connect_1;
1870
1871   return CURLE_OK;
1872 }
1873
1874 CURLcode
1875 Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
1876                                    int sockindex,
1877                                    bool *done)
1878 {
1879   return darwinssl_connect_common(conn, sockindex, TRUE, done);
1880 }
1881
1882 CURLcode
1883 Curl_darwinssl_connect(struct connectdata *conn,
1884                        int sockindex)
1885 {
1886   CURLcode retcode;
1887   bool done = FALSE;
1888
1889   retcode = darwinssl_connect_common(conn, sockindex, FALSE, &done);
1890
1891   if(retcode)
1892     return retcode;
1893
1894   DEBUGASSERT(done);
1895
1896   return CURLE_OK;
1897 }
1898
1899 void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
1900 {
1901   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1902
1903   if(connssl->ssl_ctx) {
1904     (void)SSLClose(connssl->ssl_ctx);
1905 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1906     if(SSLCreateContext != NULL)
1907       CFRelease(connssl->ssl_ctx);
1908 #if CURL_SUPPORT_MAC_10_8
1909     else
1910       (void)SSLDisposeContext(connssl->ssl_ctx);
1911 #endif  /* CURL_SUPPORT_MAC_10_8 */
1912 #else
1913     (void)SSLDisposeContext(connssl->ssl_ctx);
1914 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1915     connssl->ssl_ctx = NULL;
1916   }
1917   connssl->ssl_sockfd = 0;
1918 }
1919
1920 void Curl_darwinssl_close_all(struct SessionHandle *data)
1921 {
1922   /* SecureTransport doesn't separate sessions from contexts, so... */
1923   (void)data;
1924 }
1925
1926 int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
1927 {
1928   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1929   struct SessionHandle *data = conn->data;
1930   ssize_t nread;
1931   int what;
1932   int rc;
1933   char buf[120];
1934
1935   if(!connssl->ssl_ctx)
1936     return 0;
1937
1938   if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
1939     return 0;
1940
1941   Curl_darwinssl_close(conn, sockindex);
1942
1943   rc = 0;
1944
1945   what = Curl_socket_ready(conn->sock[sockindex],
1946                            CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
1947
1948   for(;;) {
1949     if(what < 0) {
1950       /* anything that gets here is fatally bad */
1951       failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1952       rc = -1;
1953       break;
1954     }
1955
1956     if(!what) {                                /* timeout */
1957       failf(data, "SSL shutdown timeout");
1958       break;
1959     }
1960
1961     /* Something to read, let's do it and hope that it is the close
1962      notify alert from the server. No way to SSL_Read now, so use read(). */
1963
1964     nread = read(conn->sock[sockindex], buf, sizeof(buf));
1965
1966     if(nread < 0) {
1967       failf(data, "read: %s", strerror(errno));
1968       rc = -1;
1969     }
1970
1971     if(nread <= 0)
1972       break;
1973
1974     what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
1975   }
1976
1977   return rc;
1978 }
1979
1980 void Curl_darwinssl_session_free(void *ptr)
1981 {
1982   /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
1983      cached session ID inside the Security framework. There is a private
1984      function that does this, but I don't want to have to explain to you why I
1985      got your application rejected from the App Store due to the use of a
1986      private API, so the best we can do is free up our own char array that we
1987      created way back in darwinssl_connect_step1... */
1988   Curl_safefree(ptr);
1989 }
1990
1991 size_t Curl_darwinssl_version(char *buffer, size_t size)
1992 {
1993   return snprintf(buffer, size, "SecureTransport");
1994 }
1995
1996 /*
1997  * This function uses SSLGetSessionState to determine connection status.
1998  *
1999  * Return codes:
2000  *     1 means the connection is still in place
2001  *     0 means the connection has been closed
2002  *    -1 means the connection status is unknown
2003  */
2004 int Curl_darwinssl_check_cxn(struct connectdata *conn)
2005 {
2006   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2007   OSStatus err;
2008   SSLSessionState state;
2009
2010   if(connssl->ssl_ctx) {
2011     err = SSLGetSessionState(connssl->ssl_ctx, &state);
2012     if(err == noErr)
2013       return state == kSSLConnected || state == kSSLHandshake;
2014     return -1;
2015   }
2016   return 0;
2017 }
2018
2019 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2020                                  int connindex)
2021 {
2022   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2023   OSStatus err;
2024   size_t buffer;
2025
2026   if(connssl->ssl_ctx) {  /* SSL is in use */
2027     err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
2028     if(err == noErr)
2029       return buffer > 0UL;
2030     return false;
2031   }
2032   else
2033     return false;
2034 }
2035
2036 void Curl_darwinssl_random(struct SessionHandle *data,
2037                            unsigned char *entropy,
2038                            size_t length)
2039 {
2040   /* arc4random_buf() isn't available on cats older than Lion, so let's
2041      do this manually for the benefit of the older cats. */
2042   size_t i;
2043   u_int32_t random_number = 0;
2044
2045   for(i = 0 ; i < length ; i++) {
2046     if(i % sizeof(u_int32_t) == 0)
2047       random_number = arc4random();
2048     entropy[i] = random_number & 0xFF;
2049     random_number >>= 8;
2050   }
2051   i = random_number = 0;
2052   (void)data;
2053 }
2054
2055 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2056                            size_t tmplen,
2057                            unsigned char *md5sum, /* output */
2058                            size_t md5len)
2059 {
2060   (void)md5len;
2061   (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2062 }
2063
2064 static ssize_t darwinssl_send(struct connectdata *conn,
2065                               int sockindex,
2066                               const void *mem,
2067                               size_t len,
2068                               CURLcode *curlcode)
2069 {
2070   /*struct SessionHandle *data = conn->data;*/
2071   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2072   size_t processed = 0UL;
2073   OSStatus err;
2074
2075   /* The SSLWrite() function works a little differently than expected. The
2076      fourth argument (processed) is currently documented in Apple's
2077      documentation as: "On return, the length, in bytes, of the data actually
2078      written."
2079
2080      Now, one could interpret that as "written to the socket," but actually,
2081      it returns the amount of data that was written to a buffer internal to
2082      the SSLContextRef instead. So it's possible for SSLWrite() to return
2083      errSSLWouldBlock and a number of bytes "written" because those bytes were
2084      encrypted and written to a buffer, not to the socket.
2085
2086      So if this happens, then we need to keep calling SSLWrite() over and
2087      over again with no new data until it quits returning errSSLWouldBlock. */
2088
2089   /* Do we have buffered data to write from the last time we were called? */
2090   if(connssl->ssl_write_buffered_length) {
2091     /* Write the buffered data: */
2092     err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
2093     switch (err) {
2094       case noErr:
2095         /* processed is always going to be 0 because we didn't write to
2096            the buffer, so return how much was written to the socket */
2097         processed = connssl->ssl_write_buffered_length;
2098         connssl->ssl_write_buffered_length = 0UL;
2099         break;
2100       case errSSLWouldBlock: /* argh, try again */
2101         *curlcode = CURLE_AGAIN;
2102         return -1L;
2103       default:
2104         failf(conn->data, "SSLWrite() returned error %d", err);
2105         *curlcode = CURLE_SEND_ERROR;
2106         return -1L;
2107     }
2108   }
2109   else {
2110     /* We've got new data to write: */
2111     err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
2112     if(err != noErr) {
2113       switch (err) {
2114         case errSSLWouldBlock:
2115           /* Data was buffered but not sent, we have to tell the caller
2116              to try sending again, and remember how much was buffered */
2117           connssl->ssl_write_buffered_length = len;
2118           *curlcode = CURLE_AGAIN;
2119           return -1L;
2120         default:
2121           failf(conn->data, "SSLWrite() returned error %d", err);
2122           *curlcode = CURLE_SEND_ERROR;
2123           return -1L;
2124       }
2125     }
2126   }
2127   return (ssize_t)processed;
2128 }
2129
2130 static ssize_t darwinssl_recv(struct connectdata *conn,
2131                               int num,
2132                               char *buf,
2133                               size_t buffersize,
2134                               CURLcode *curlcode)
2135 {
2136   /*struct SessionHandle *data = conn->data;*/
2137   struct ssl_connect_data *connssl = &conn->ssl[num];
2138   size_t processed = 0UL;
2139   OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
2140
2141   if(err != noErr) {
2142     switch (err) {
2143       case errSSLWouldBlock:  /* return how much we read (if anything) */
2144         if(processed)
2145           return (ssize_t)processed;
2146         *curlcode = CURLE_AGAIN;
2147         return -1L;
2148         break;
2149
2150       /* errSSLClosedGraceful - server gracefully shut down the SSL session
2151          errSSLClosedNoNotify - server hung up on us instead of sending a
2152            closure alert notice, read() is returning 0
2153          Either way, inform the caller that the server disconnected. */
2154       case errSSLClosedGraceful:
2155       case errSSLClosedNoNotify:
2156         *curlcode = CURLE_OK;
2157         return -1L;
2158         break;
2159
2160       default:
2161         failf(conn->data, "SSLRead() return error %d", err);
2162         *curlcode = CURLE_RECV_ERROR;
2163         return -1L;
2164         break;
2165     }
2166   }
2167   return (ssize_t)processed;
2168 }
2169
2170 #endif /* USE_DARWINSSL */