1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2012 - 2013, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012 - 2013, 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: */
115static 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
179static 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
219CF_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
364CF_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
776CF_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. */
810CF_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: */
840static 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
879static 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
930static 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) {
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      CFRelease(items);
964    }
965    CFRelease(options);
966    CFRelease(pkcs_data);
967  }
968#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
969  if(password)
970    CFRelease(password);
971  CFRelease(pkcs_url);
972  return status;
973}
974
975/* This code was borrowed from nss.c, with some modifications:
976 * Determine whether the nickname passed in is a filename that needs to
977 * be loaded as a PEM or a regular NSS nickname.
978 *
979 * returns 1 for a file
980 * returns 0 for not a file
981 */
982CF_INLINE bool is_file(const char *filename)
983{
984  struct_stat st;
985
986  if(filename == NULL)
987    return false;
988
989  if(stat(filename, &st) == 0)
990    return S_ISREG(st.st_mode);
991  return false;
992}
993
994static CURLcode darwinssl_connect_step1(struct connectdata *conn,
995                                        int sockindex)
996{
997  struct SessionHandle *data = conn->data;
998  curl_socket_t sockfd = conn->sock[sockindex];
999  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1000#ifdef ENABLE_IPV6
1001  struct in6_addr addr;
1002#else
1003  struct in_addr addr;
1004#endif /* ENABLE_IPV6 */
1005  size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1006  SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1007  char *ssl_sessionid;
1008  size_t ssl_sessionid_len;
1009  OSStatus err = noErr;
1010#if CURL_BUILD_MAC
1011  int darwinver_maj = 0, darwinver_min = 0;
1012
1013  GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1014#endif /* CURL_BUILD_MAC */
1015
1016#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1017  if(SSLCreateContext != NULL) {  /* use the newer API if avaialble */
1018    if(connssl->ssl_ctx)
1019      CFRelease(connssl->ssl_ctx);
1020    connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1021    if(!connssl->ssl_ctx) {
1022      failf(data, "SSL: couldn't create a context!");
1023      return CURLE_OUT_OF_MEMORY;
1024    }
1025  }
1026  else {
1027  /* The old ST API does not exist under iOS, so don't compile it: */
1028#if CURL_SUPPORT_MAC_10_8
1029    if(connssl->ssl_ctx)
1030      (void)SSLDisposeContext(connssl->ssl_ctx);
1031    err = SSLNewContext(false, &(connssl->ssl_ctx));
1032    if(err != noErr) {
1033      failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1034      return CURLE_OUT_OF_MEMORY;
1035    }
1036#endif /* CURL_SUPPORT_MAC_10_8 */
1037  }
1038#else
1039  if(connssl->ssl_ctx)
1040    (void)SSLDisposeContext(connssl->ssl_ctx);
1041  err = SSLNewContext(false, &(connssl->ssl_ctx));
1042  if(err != noErr) {
1043    failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1044    return CURLE_OUT_OF_MEMORY;
1045  }
1046#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1047  connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1048
1049  /* check to see if we've been told to use an explicit SSL/TLS version */
1050#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1051  if(SSLSetProtocolVersionMax != NULL) {
1052    switch(data->set.ssl.version) {
1053      case CURL_SSLVERSION_DEFAULT: default:
1054        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1055        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1056        break;
1057      case CURL_SSLVERSION_TLSv1:
1058        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1059        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1060        break;
1061      case CURL_SSLVERSION_TLSv1_0:
1062        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1063        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
1064        break;
1065      case CURL_SSLVERSION_TLSv1_1:
1066        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
1067        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
1068        break;
1069      case CURL_SSLVERSION_TLSv1_2:
1070        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
1071        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1072        break;
1073      case CURL_SSLVERSION_SSLv3:
1074        (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1075        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
1076        break;
1077      case CURL_SSLVERSION_SSLv2:
1078        err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
1079        if(err != noErr) {
1080          failf(data, "Your version of the OS does not support SSLv2");
1081          return CURLE_SSL_CONNECT_ERROR;
1082        }
1083        (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
1084    }
1085  }
1086  else {
1087#if CURL_SUPPORT_MAC_10_8
1088    (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1089                                       kSSLProtocolAll,
1090                                       false);
1091    switch (data->set.ssl.version) {
1092      case CURL_SSLVERSION_DEFAULT: default:
1093        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1094                                           kSSLProtocol3,
1095                                           true);
1096        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1097                                           kTLSProtocol1,
1098                                           true);
1099        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1100                                           kTLSProtocol11,
1101                                           true);
1102        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1103                                           kTLSProtocol12,
1104                                           true);
1105        break;
1106      case CURL_SSLVERSION_TLSv1:
1107        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1108                                           kTLSProtocol1,
1109                                           true);
1110        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1111                                           kTLSProtocol11,
1112                                           true);
1113        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1114                                           kTLSProtocol12,
1115                                           true);
1116        break;
1117      case CURL_SSLVERSION_TLSv1_0:
1118        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1119                                           kTLSProtocol1,
1120                                           true);
1121        break;
1122      case CURL_SSLVERSION_TLSv1_1:
1123        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1124                                           kTLSProtocol11,
1125                                           true);
1126        break;
1127      case CURL_SSLVERSION_TLSv1_2:
1128        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1129                                           kTLSProtocol12,
1130                                           true);
1131        break;
1132      case CURL_SSLVERSION_SSLv3:
1133        (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1134                                           kSSLProtocol3,
1135                                           true);
1136        break;
1137      case CURL_SSLVERSION_SSLv2:
1138        err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1139                                           kSSLProtocol2,
1140                                           true);
1141        if(err != noErr) {
1142          failf(data, "Your version of the OS does not support SSLv2");
1143          return CURLE_SSL_CONNECT_ERROR;
1144        }
1145        break;
1146    }
1147#endif  /* CURL_SUPPORT_MAC_10_8 */
1148  }
1149#else
1150  (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
1151  switch(data->set.ssl.version) {
1152    default:
1153    case CURL_SSLVERSION_DEFAULT:
1154      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1155                                         kSSLProtocol3,
1156                                         true);
1157      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1158                                         kTLSProtocol1,
1159                                         true);
1160      break;
1161    case CURL_SSLVERSION_TLSv1:
1162    case CURL_SSLVERSION_TLSv1_0:
1163      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1164                                         kTLSProtocol1,
1165                                         true);
1166      break;
1167    case CURL_SSLVERSION_TLSv1_1:
1168      failf(data, "Your version of the OS does not support TLSv1.1");
1169      return CURLE_SSL_CONNECT_ERROR;
1170    case CURL_SSLVERSION_TLSv1_2:
1171      failf(data, "Your version of the OS does not support TLSv1.2");
1172      return CURLE_SSL_CONNECT_ERROR;
1173    case CURL_SSLVERSION_SSLv2:
1174      err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1175                                         kSSLProtocol2,
1176                                         true);
1177      if(err != noErr) {
1178        failf(data, "Your version of the OS does not support SSLv2");
1179        return CURLE_SSL_CONNECT_ERROR;
1180      }
1181      break;
1182    case CURL_SSLVERSION_SSLv3:
1183      (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1184                                         kSSLProtocol3,
1185                                         true);
1186      break;
1187  }
1188#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1189
1190  if(data->set.str[STRING_KEY]) {
1191    infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1192                "Transport. The private key must be in the Keychain.\n");
1193  }
1194
1195  if(data->set.str[STRING_CERT]) {
1196    SecIdentityRef cert_and_key = NULL;
1197    bool is_cert_file = is_file(data->set.str[STRING_CERT]);
1198
1199    /* User wants to authenticate with a client cert. Look for it:
1200       If we detect that this is a file on disk, then let's load it.
1201       Otherwise, assume that the user wants to use an identity loaded
1202       from the Keychain. */
1203    if(is_cert_file) {
1204      if(!data->set.str[STRING_CERT_TYPE])
1205        infof(data, "WARNING: SSL: Certificate type not set, assuming "
1206                    "PKCS#12 format.\n");
1207      else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
1208        strlen(data->set.str[STRING_CERT_TYPE])) != 0)
1209        infof(data, "WARNING: SSL: The Security framework only supports "
1210                    "loading identities that are in PKCS#12 format.\n");
1211
1212      err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
1213        data->set.str[STRING_KEY_PASSWD], &cert_and_key);
1214    }
1215    else
1216      err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
1217
1218    if(err == noErr) {
1219      SecCertificateRef cert = NULL;
1220      CFTypeRef certs_c[1];
1221      CFArrayRef certs;
1222
1223      /* If we found one, print it out: */
1224      err = SecIdentityCopyCertificate(cert_and_key, &cert);
1225      if(err == noErr) {
1226        CFStringRef cert_summary = CopyCertSubject(cert);
1227        char cert_summary_c[128];
1228
1229        if(cert_summary) {
1230          memset(cert_summary_c, 0, 128);
1231          if(CFStringGetCString(cert_summary,
1232                                cert_summary_c,
1233                                128,
1234                                kCFStringEncodingUTF8)) {
1235            infof(data, "Client certificate: %s\n", cert_summary_c);
1236          }
1237          CFRelease(cert_summary);
1238          CFRelease(cert);
1239        }
1240      }
1241      certs_c[0] = cert_and_key;
1242      certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1243                            &kCFTypeArrayCallBacks);
1244      err = SSLSetCertificate(connssl->ssl_ctx, certs);
1245      if(certs)
1246        CFRelease(certs);
1247      if(err != noErr) {
1248        failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1249        return CURLE_SSL_CERTPROBLEM;
1250      }
1251      CFRelease(cert_and_key);
1252    }
1253    else {
1254      switch(err) {
1255        case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1256          failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1257                      "and its private key.", data->set.str[STRING_CERT]);
1258          break;
1259        case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1260          failf(data, "SSL: Couldn't make sense of the data in the "
1261                      "certificate \"%s\" and its private key.",
1262                      data->set.str[STRING_CERT]);
1263          break;
1264        case -25260: /* errSecPassphraseRequired */
1265          failf(data, "SSL The certificate \"%s\" requires a password.",
1266                      data->set.str[STRING_CERT]);
1267          break;
1268        case errSecItemNotFound:
1269          failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1270                      "key in the Keychain.", data->set.str[STRING_CERT]);
1271          break;
1272        default:
1273          failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1274                      "key: OSStatus %d", data->set.str[STRING_CERT], err);
1275          break;
1276      }
1277      return CURLE_SSL_CERTPROBLEM;
1278    }
1279  }
1280
1281  /* SSL always tries to verify the peer, this only says whether it should
1282   * fail to connect if the verification fails, or if it should continue
1283   * anyway. In the latter case the result of the verification is checked with
1284   * SSL_get_verify_result() below. */
1285#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1286  /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1287     a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1288     works, it doesn't work as expected under Snow Leopard or Lion.
1289     So we need to call SSLSetEnableCertVerify() on those older cats in order
1290     to disable certificate validation if the user turned that off.
1291     (SecureTransport will always validate the certificate chain by
1292     default.) */
1293  /* (Note: Darwin 12.x.x is Mountain Lion.) */
1294#if CURL_BUILD_MAC
1295  if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
1296#else
1297  if(SSLSetSessionOption != NULL) {
1298#endif /* CURL_BUILD_MAC */
1299    err = SSLSetSessionOption(connssl->ssl_ctx,
1300                              kSSLSessionOptionBreakOnServerAuth,
1301                              data->set.ssl.verifypeer?false:true);
1302    if(err != noErr) {
1303      failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1304      return CURLE_SSL_CONNECT_ERROR;
1305    }
1306  }
1307  else {
1308#if CURL_SUPPORT_MAC_10_8
1309    err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1310                                 data->set.ssl.verifypeer?true:false);
1311    if(err != noErr) {
1312      failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1313      return CURLE_SSL_CONNECT_ERROR;
1314    }
1315#endif /* CURL_SUPPORT_MAC_10_8 */
1316  }
1317#else
1318  err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1319                               data->set.ssl.verifypeer?true:false);
1320  if(err != noErr) {
1321    failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1322    return CURLE_SSL_CONNECT_ERROR;
1323  }
1324#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1325
1326  /* Configure hostname check. SNI is used if available.
1327   * Both hostname check and SNI require SSLSetPeerDomainName().
1328   * Also: the verifyhost setting influences SNI usage */
1329  if(data->set.ssl.verifyhost) {
1330    err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1331    strlen(conn->host.name));
1332
1333    if(err != noErr) {
1334      infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1335            err);
1336    }
1337
1338    if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
1339  #ifdef ENABLE_IPV6
1340    || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
1341  #endif
1342       ) {
1343         infof(data, "WARNING: using IP address, SNI is being disabled by "
1344         "the OS.\n");
1345    }
1346  }
1347
1348  /* Disable cipher suites that ST supports but are not safe. These ciphers
1349     are unlikely to be used in any case since ST gives other ciphers a much
1350     higher priority, but it's probably better that we not connect at all than
1351     to give the user a false sense of security if the server only supports
1352     insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1353  (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1354  all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1355  allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1356  if(all_ciphers && allowed_ciphers &&
1357     SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1358       &all_ciphers_count) == noErr) {
1359    for(i = 0UL ; i < all_ciphers_count ; i++) {
1360#if CURL_BUILD_MAC
1361     /* There's a known bug in early versions of Mountain Lion where ST's ECC
1362        ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1363        Work around the problem here by disabling those ciphers if we are
1364        running in an affected version of OS X. */
1365      if(darwinver_maj == 12 && darwinver_min <= 3 &&
1366         all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1367           continue;
1368      }
1369#endif /* CURL_BUILD_MAC */
1370      switch(all_ciphers[i]) {
1371        /* Disable NULL ciphersuites: */
1372        case SSL_NULL_WITH_NULL_NULL:
1373        case SSL_RSA_WITH_NULL_MD5:
1374        case SSL_RSA_WITH_NULL_SHA:
1375        case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1376        case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1377        case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1378        case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1379        case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1380        case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1381        case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1382        case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1383        case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1384        case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1385        case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1386        case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1387        case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1388        case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1389        case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1390        /* Disable anonymous ciphersuites: */
1391        case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1392        case SSL_DH_anon_WITH_RC4_128_MD5:
1393        case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1394        case SSL_DH_anon_WITH_DES_CBC_SHA:
1395        case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1396        case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1397        case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1398        case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1399        case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1400        case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1401        case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1402        case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1403        case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1404        case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1405        case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1406        case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1407        /* Disable weak key ciphersuites: */
1408        case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1409        case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1410        case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1411        case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1412        case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1413        case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1414        case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1415        case SSL_RSA_WITH_DES_CBC_SHA:
1416        case SSL_DH_DSS_WITH_DES_CBC_SHA:
1417        case SSL_DH_RSA_WITH_DES_CBC_SHA:
1418        case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1419        case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1420        /* Disable IDEA: */
1421        case SSL_RSA_WITH_IDEA_CBC_SHA:
1422        case SSL_RSA_WITH_IDEA_CBC_MD5:
1423          break;
1424        default: /* enable everything else */
1425          allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1426          break;
1427      }
1428    }
1429    err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1430                               allowed_ciphers_count);
1431    if(err != noErr) {
1432      failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1433      return CURLE_SSL_CONNECT_ERROR;
1434    }
1435  }
1436  else {
1437    Curl_safefree(all_ciphers);
1438    Curl_safefree(allowed_ciphers);
1439    failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1440    return CURLE_OUT_OF_MEMORY;
1441  }
1442  Curl_safefree(all_ciphers);
1443  Curl_safefree(allowed_ciphers);
1444
1445#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1446  /* We want to enable 1/n-1 when using a CBC cipher unless the user
1447     specifically doesn't want us doing that: */
1448  if(SSLSetSessionOption != NULL)
1449    SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1450                      !data->set.ssl_enable_beast);
1451#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1452
1453  /* Check if there's a cached ID we can/should use here! */
1454  if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1455    &ssl_sessionid_len)) {
1456    /* we got a session id, use it! */
1457    err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1458    if(err != noErr) {
1459      failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1460      return CURLE_SSL_CONNECT_ERROR;
1461    }
1462    /* Informational message */
1463    infof(data, "SSL re-using session ID\n");
1464  }
1465  /* If there isn't one, then let's make one up! This has to be done prior
1466     to starting the handshake. */
1467  else {
1468    CURLcode retcode;
1469
1470    ssl_sessionid = malloc(256*sizeof(char));
1471    ssl_sessionid_len = snprintf(ssl_sessionid, 256, "curl:%s:%hu",
1472      conn->host.name, conn->remote_port);
1473    err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1474    if(err != noErr) {
1475      failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1476      return CURLE_SSL_CONNECT_ERROR;
1477    }
1478    retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1479    if(retcode!= CURLE_OK) {
1480      failf(data, "failed to store ssl session");
1481      return retcode;
1482    }
1483  }
1484
1485  err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1486  if(err != noErr) {
1487    failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1488    return CURLE_SSL_CONNECT_ERROR;
1489  }
1490
1491  /* pass the raw socket into the SSL layers */
1492  /* We need to store the FD in a constant memory address, because
1493   * SSLSetConnection() will not copy that address. I've found that
1494   * conn->sock[sockindex] may change on its own. */
1495  connssl->ssl_sockfd = sockfd;
1496  err = SSLSetConnection(connssl->ssl_ctx, connssl);
1497  if(err != noErr) {
1498    failf(data, "SSL: SSLSetConnection() failed: %d", err);
1499    return CURLE_SSL_CONNECT_ERROR;
1500  }
1501
1502  connssl->connecting_state = ssl_connect_2;
1503  return CURLE_OK;
1504}
1505
1506static CURLcode
1507darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1508{
1509  struct SessionHandle *data = conn->data;
1510  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1511  OSStatus err;
1512  SSLCipherSuite cipher;
1513  SSLProtocol protocol = 0;
1514
1515  DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1516              || ssl_connect_2_reading == connssl->connecting_state
1517              || ssl_connect_2_writing == connssl->connecting_state);
1518
1519  /* Here goes nothing: */
1520  err = SSLHandshake(connssl->ssl_ctx);
1521
1522  if(err != noErr) {
1523    switch (err) {
1524      case errSSLWouldBlock:  /* they're not done with us yet */
1525        connssl->connecting_state = connssl->ssl_direction ?
1526            ssl_connect_2_writing : ssl_connect_2_reading;
1527        return CURLE_OK;
1528
1529      /* The below is errSSLServerAuthCompleted; it's not defined in
1530        Leopard's headers */
1531      case -9841:
1532        /* the documentation says we need to call SSLHandshake() again */
1533        return darwinssl_connect_step2(conn, sockindex);
1534
1535      /* These are all certificate problems with the server: */
1536      case errSSLXCertChainInvalid:
1537        failf(data, "SSL certificate problem: Invalid certificate chain");
1538        return CURLE_SSL_CACERT;
1539      case errSSLUnknownRootCert:
1540        failf(data, "SSL certificate problem: Untrusted root certificate");
1541        return CURLE_SSL_CACERT;
1542      case errSSLNoRootCert:
1543        failf(data, "SSL certificate problem: No root certificate");
1544        return CURLE_SSL_CACERT;
1545      case errSSLCertExpired:
1546        failf(data, "SSL certificate problem: Certificate chain had an "
1547              "expired certificate");
1548        return CURLE_SSL_CACERT;
1549      case errSSLBadCert:
1550        failf(data, "SSL certificate problem: Couldn't understand the server "
1551              "certificate format");
1552        return CURLE_SSL_CONNECT_ERROR;
1553
1554      /* These are all certificate problems with the client: */
1555      case errSecAuthFailed:
1556        failf(data, "SSL authentication failed");
1557        return CURLE_SSL_CONNECT_ERROR;
1558      case errSSLPeerHandshakeFail:
1559        failf(data, "SSL peer handshake failed, the server most likely "
1560              "requires a client certificate to connect");
1561        return CURLE_SSL_CONNECT_ERROR;
1562      case errSSLPeerUnknownCA:
1563        failf(data, "SSL server rejected the client certificate due to "
1564              "the certificate being signed by an unknown certificate "
1565              "authority");
1566        return CURLE_SSL_CONNECT_ERROR;
1567
1568      /* This error is raised if the server's cert didn't match the server's
1569         host name: */
1570      case errSSLHostNameMismatch:
1571        failf(data, "SSL certificate peer verification failed, the "
1572              "certificate did not match \"%s\"\n", conn->host.dispname);
1573        return CURLE_PEER_FAILED_VERIFICATION;
1574
1575      /* Generic handshake errors: */
1576      case errSSLConnectionRefused:
1577        failf(data, "Server dropped the connection during the SSL handshake");
1578        return CURLE_SSL_CONNECT_ERROR;
1579      case errSSLClosedAbort:
1580        failf(data, "Server aborted the SSL handshake");
1581        return CURLE_SSL_CONNECT_ERROR;
1582      case errSSLNegotiation:
1583        failf(data, "Could not negotiate an SSL cipher suite with the server");
1584        return CURLE_SSL_CONNECT_ERROR;
1585      /* Sometimes paramErr happens with buggy ciphers: */
1586      case paramErr: case errSSLInternal:
1587        failf(data, "Internal SSL engine error encountered during the "
1588              "SSL handshake");
1589        return CURLE_SSL_CONNECT_ERROR;
1590      case errSSLFatalAlert:
1591        failf(data, "Fatal SSL engine error encountered during the SSL "
1592              "handshake");
1593        return CURLE_SSL_CONNECT_ERROR;
1594      default:
1595        failf(data, "Unknown SSL protocol error in connection to %s:%d",
1596              conn->host.name, err);
1597        return CURLE_SSL_CONNECT_ERROR;
1598    }
1599  }
1600  else {
1601    /* we have been connected fine, we're not waiting for anything else. */
1602    connssl->connecting_state = ssl_connect_3;
1603
1604    /* Informational message */
1605    (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1606    (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1607    switch (protocol) {
1608      case kSSLProtocol2:
1609        infof(data, "SSL 2.0 connection using %s\n",
1610              SSLCipherNameForNumber(cipher));
1611        break;
1612      case kSSLProtocol3:
1613        infof(data, "SSL 3.0 connection using %s\n",
1614              SSLCipherNameForNumber(cipher));
1615        break;
1616      case kTLSProtocol1:
1617        infof(data, "TLS 1.0 connection using %s\n",
1618              TLSCipherNameForNumber(cipher));
1619        break;
1620#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1621      case kTLSProtocol11:
1622        infof(data, "TLS 1.1 connection using %s\n",
1623              TLSCipherNameForNumber(cipher));
1624        break;
1625      case kTLSProtocol12:
1626        infof(data, "TLS 1.2 connection using %s\n",
1627              TLSCipherNameForNumber(cipher));
1628        break;
1629#endif
1630      default:
1631        infof(data, "Unknown protocol connection\n");
1632        break;
1633    }
1634
1635    return CURLE_OK;
1636  }
1637}
1638
1639static CURLcode
1640darwinssl_connect_step3(struct connectdata *conn,
1641                        int sockindex)
1642{
1643  struct SessionHandle *data = conn->data;
1644  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1645  CFStringRef server_cert_summary;
1646  char server_cert_summary_c[128];
1647  CFArrayRef server_certs = NULL;
1648  SecCertificateRef server_cert;
1649  OSStatus err;
1650  CFIndex i, count;
1651  SecTrustRef trust = NULL;
1652
1653  /* There is no step 3!
1654   * Well, okay, if verbose mode is on, let's print the details of the
1655   * server certificates. */
1656#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1657#if CURL_BUILD_IOS
1658#pragma unused(server_certs)
1659  err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1660  /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1661     a null trust, so be on guard for that: */
1662  if(err == noErr && trust) {
1663    count = SecTrustGetCertificateCount(trust);
1664    for(i = 0L ; i < count ; i++) {
1665      server_cert = SecTrustGetCertificateAtIndex(trust, i);
1666      server_cert_summary = CopyCertSubject(server_cert);
1667      memset(server_cert_summary_c, 0, 128);
1668      if(CFStringGetCString(server_cert_summary,
1669                            server_cert_summary_c,
1670                            128,
1671                            kCFStringEncodingUTF8)) {
1672        infof(data, "Server certificate: %s\n", server_cert_summary_c);
1673      }
1674      CFRelease(server_cert_summary);
1675    }
1676    CFRelease(trust);
1677  }
1678#else
1679  /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
1680     The function SecTrustGetCertificateAtIndex() is officially present
1681     in Lion, but it is unfortunately also present in Snow Leopard as
1682     private API and doesn't work as expected. So we have to look for
1683     a different symbol to make sure this code is only executed under
1684     Lion or later. */
1685  if(SecTrustEvaluateAsync != NULL) {
1686#pragma unused(server_certs)
1687    err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1688    /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1689       a null trust, so be on guard for that: */
1690    if(err == noErr && trust) {
1691      count = SecTrustGetCertificateCount(trust);
1692      for(i = 0L ; i < count ; i++) {
1693        server_cert = SecTrustGetCertificateAtIndex(trust, i);
1694        server_cert_summary = CopyCertSubject(server_cert);
1695        memset(server_cert_summary_c, 0, 128);
1696        if(CFStringGetCString(server_cert_summary,
1697                              server_cert_summary_c,
1698                              128,
1699                              kCFStringEncodingUTF8)) {
1700          infof(data, "Server certificate: %s\n", server_cert_summary_c);
1701        }
1702        CFRelease(server_cert_summary);
1703      }
1704      CFRelease(trust);
1705    }
1706  }
1707  else {
1708#if CURL_SUPPORT_MAC_10_8
1709    err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1710    /* Just in case SSLCopyPeerCertificates() returns null too... */
1711    if(err == noErr && server_certs) {
1712      count = CFArrayGetCount(server_certs);
1713      for(i = 0L ; i < count ; i++) {
1714        server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
1715                                                                i);
1716
1717        server_cert_summary = CopyCertSubject(server_cert);
1718        memset(server_cert_summary_c, 0, 128);
1719        if(CFStringGetCString(server_cert_summary,
1720                              server_cert_summary_c,
1721                              128,
1722                              kCFStringEncodingUTF8)) {
1723          infof(data, "Server certificate: %s\n", server_cert_summary_c);
1724        }
1725        CFRelease(server_cert_summary);
1726      }
1727      CFRelease(server_certs);
1728    }
1729#endif /* CURL_SUPPORT_MAC_10_8 */
1730  }
1731#endif /* CURL_BUILD_IOS */
1732#else
1733#pragma unused(trust)
1734  err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1735  if(err == noErr) {
1736    count = CFArrayGetCount(server_certs);
1737    for(i = 0L ; i < count ; i++) {
1738      server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
1739      server_cert_summary = CopyCertSubject(server_cert);
1740      memset(server_cert_summary_c, 0, 128);
1741      if(CFStringGetCString(server_cert_summary,
1742                            server_cert_summary_c,
1743                            128,
1744                            kCFStringEncodingUTF8)) {
1745        infof(data, "Server certificate: %s\n", server_cert_summary_c);
1746      }
1747      CFRelease(server_cert_summary);
1748    }
1749    CFRelease(server_certs);
1750  }
1751#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1752
1753  connssl->connecting_state = ssl_connect_done;
1754  return CURLE_OK;
1755}
1756
1757static Curl_recv darwinssl_recv;
1758static Curl_send darwinssl_send;
1759
1760static CURLcode
1761darwinssl_connect_common(struct connectdata *conn,
1762                         int sockindex,
1763                         bool nonblocking,
1764                         bool *done)
1765{
1766  CURLcode retcode;
1767  struct SessionHandle *data = conn->data;
1768  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1769  curl_socket_t sockfd = conn->sock[sockindex];
1770  long timeout_ms;
1771  int what;
1772
1773  /* check if the connection has already been established */
1774  if(ssl_connection_complete == connssl->state) {
1775    *done = TRUE;
1776    return CURLE_OK;
1777  }
1778
1779  if(ssl_connect_1==connssl->connecting_state) {
1780    /* Find out how much more time we're allowed */
1781    timeout_ms = Curl_timeleft(data, NULL, TRUE);
1782
1783    if(timeout_ms < 0) {
1784      /* no need to continue if time already is up */
1785      failf(data, "SSL connection timeout");
1786      return CURLE_OPERATION_TIMEDOUT;
1787    }
1788    retcode = darwinssl_connect_step1(conn, sockindex);
1789    if(retcode)
1790      return retcode;
1791  }
1792
1793  while(ssl_connect_2 == connssl->connecting_state ||
1794        ssl_connect_2_reading == connssl->connecting_state ||
1795        ssl_connect_2_writing == connssl->connecting_state) {
1796
1797    /* check allowed time left */
1798    timeout_ms = Curl_timeleft(data, NULL, TRUE);
1799
1800    if(timeout_ms < 0) {
1801      /* no need to continue if time already is up */
1802      failf(data, "SSL connection timeout");
1803      return CURLE_OPERATION_TIMEDOUT;
1804    }
1805
1806    /* if ssl is expecting something, check if it's available. */
1807    if(connssl->connecting_state == ssl_connect_2_reading
1808       || connssl->connecting_state == ssl_connect_2_writing) {
1809
1810      curl_socket_t writefd = ssl_connect_2_writing ==
1811      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1812      curl_socket_t readfd = ssl_connect_2_reading ==
1813      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1814
1815      what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
1816      if(what < 0) {
1817        /* fatal error */
1818        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1819        return CURLE_SSL_CONNECT_ERROR;
1820      }
1821      else if(0 == what) {
1822        if(nonblocking) {
1823          *done = FALSE;
1824          return CURLE_OK;
1825        }
1826        else {
1827          /* timeout */
1828          failf(data, "SSL connection timeout");
1829          return CURLE_OPERATION_TIMEDOUT;
1830        }
1831      }
1832      /* socket is readable or writable */
1833    }
1834
1835    /* Run transaction, and return to the caller if it failed or if this
1836     * connection is done nonblocking and this loop would execute again. This
1837     * permits the owner of a multi handle to abort a connection attempt
1838     * before step2 has completed while ensuring that a client using select()
1839     * or epoll() will always have a valid fdset to wait on.
1840     */
1841    retcode = darwinssl_connect_step2(conn, sockindex);
1842    if(retcode || (nonblocking &&
1843                   (ssl_connect_2 == connssl->connecting_state ||
1844                    ssl_connect_2_reading == connssl->connecting_state ||
1845                    ssl_connect_2_writing == connssl->connecting_state)))
1846      return retcode;
1847
1848  } /* repeat step2 until all transactions are done. */
1849
1850
1851  if(ssl_connect_3==connssl->connecting_state) {
1852    retcode = darwinssl_connect_step3(conn, sockindex);
1853    if(retcode)
1854      return retcode;
1855  }
1856
1857  if(ssl_connect_done==connssl->connecting_state) {
1858    connssl->state = ssl_connection_complete;
1859    conn->recv[sockindex] = darwinssl_recv;
1860    conn->send[sockindex] = darwinssl_send;
1861    *done = TRUE;
1862  }
1863  else
1864    *done = FALSE;
1865
1866  /* Reset our connect state machine */
1867  connssl->connecting_state = ssl_connect_1;
1868
1869  return CURLE_OK;
1870}
1871
1872CURLcode
1873Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
1874                                   int sockindex,
1875                                   bool *done)
1876{
1877  return darwinssl_connect_common(conn, sockindex, TRUE, done);
1878}
1879
1880CURLcode
1881Curl_darwinssl_connect(struct connectdata *conn,
1882                       int sockindex)
1883{
1884  CURLcode retcode;
1885  bool done = FALSE;
1886
1887  retcode = darwinssl_connect_common(conn, sockindex, FALSE, &done);
1888
1889  if(retcode)
1890    return retcode;
1891
1892  DEBUGASSERT(done);
1893
1894  return CURLE_OK;
1895}
1896
1897void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
1898{
1899  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1900
1901  if(connssl->ssl_ctx) {
1902    (void)SSLClose(connssl->ssl_ctx);
1903#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1904    if(SSLCreateContext != NULL)
1905      CFRelease(connssl->ssl_ctx);
1906#if CURL_SUPPORT_MAC_10_8
1907    else
1908      (void)SSLDisposeContext(connssl->ssl_ctx);
1909#endif  /* CURL_SUPPORT_MAC_10_8 */
1910#else
1911    (void)SSLDisposeContext(connssl->ssl_ctx);
1912#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1913    connssl->ssl_ctx = NULL;
1914  }
1915  connssl->ssl_sockfd = 0;
1916}
1917
1918void Curl_darwinssl_close_all(struct SessionHandle *data)
1919{
1920  /* SecureTransport doesn't separate sessions from contexts, so... */
1921  (void)data;
1922}
1923
1924int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
1925{
1926  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1927  struct SessionHandle *data = conn->data;
1928  ssize_t nread;
1929  int what;
1930  int rc;
1931  char buf[120];
1932
1933  if(!connssl->ssl_ctx)
1934    return 0;
1935
1936  if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
1937    return 0;
1938
1939  Curl_darwinssl_close(conn, sockindex);
1940
1941  rc = 0;
1942
1943  what = Curl_socket_ready(conn->sock[sockindex],
1944                           CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
1945
1946  for(;;) {
1947    if(what < 0) {
1948      /* anything that gets here is fatally bad */
1949      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1950      rc = -1;
1951      break;
1952    }
1953
1954    if(!what) {                                /* timeout */
1955      failf(data, "SSL shutdown timeout");
1956      break;
1957    }
1958
1959    /* Something to read, let's do it and hope that it is the close
1960     notify alert from the server. No way to SSL_Read now, so use read(). */
1961
1962    nread = read(conn->sock[sockindex], buf, sizeof(buf));
1963
1964    if(nread < 0) {
1965      failf(data, "read: %s", strerror(errno));
1966      rc = -1;
1967    }
1968
1969    if(nread <= 0)
1970      break;
1971
1972    what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
1973  }
1974
1975  return rc;
1976}
1977
1978void Curl_darwinssl_session_free(void *ptr)
1979{
1980  /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
1981     cached session ID inside the Security framework. There is a private
1982     function that does this, but I don't want to have to explain to you why I
1983     got your application rejected from the App Store due to the use of a
1984     private API, so the best we can do is free up our own char array that we
1985     created way back in darwinssl_connect_step1... */
1986  Curl_safefree(ptr);
1987}
1988
1989size_t Curl_darwinssl_version(char *buffer, size_t size)
1990{
1991  return snprintf(buffer, size, "SecureTransport");
1992}
1993
1994/*
1995 * This function uses SSLGetSessionState to determine connection status.
1996 *
1997 * Return codes:
1998 *     1 means the connection is still in place
1999 *     0 means the connection has been closed
2000 *    -1 means the connection status is unknown
2001 */
2002int Curl_darwinssl_check_cxn(struct connectdata *conn)
2003{
2004  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2005  OSStatus err;
2006  SSLSessionState state;
2007
2008  if(connssl->ssl_ctx) {
2009    err = SSLGetSessionState(connssl->ssl_ctx, &state);
2010    if(err == noErr)
2011      return state == kSSLConnected || state == kSSLHandshake;
2012    return -1;
2013  }
2014  return 0;
2015}
2016
2017bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2018                                 int connindex)
2019{
2020  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2021  OSStatus err;
2022  size_t buffer;
2023
2024  if(connssl->ssl_ctx) {  /* SSL is in use */
2025    err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
2026    if(err == noErr)
2027      return buffer > 0UL;
2028    return false;
2029  }
2030  else
2031    return false;
2032}
2033
2034void Curl_darwinssl_random(struct SessionHandle *data,
2035                           unsigned char *entropy,
2036                           size_t length)
2037{
2038  /* arc4random_buf() isn't available on cats older than Lion, so let's
2039     do this manually for the benefit of the older cats. */
2040  size_t i;
2041  u_int32_t random_number = 0;
2042
2043  for(i = 0 ; i < length ; i++) {
2044    if(i % sizeof(u_int32_t) == 0)
2045      random_number = arc4random();
2046    entropy[i] = random_number & 0xFF;
2047    random_number >>= 8;
2048  }
2049  i = random_number = 0;
2050  (void)data;
2051}
2052
2053void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2054                           size_t tmplen,
2055                           unsigned char *md5sum, /* output */
2056                           size_t md5len)
2057{
2058  (void)md5len;
2059  (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2060}
2061
2062static ssize_t darwinssl_send(struct connectdata *conn,
2063                              int sockindex,
2064                              const void *mem,
2065                              size_t len,
2066                              CURLcode *curlcode)
2067{
2068  /*struct SessionHandle *data = conn->data;*/
2069  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2070  size_t processed = 0UL;
2071  OSStatus err;
2072
2073  /* The SSLWrite() function works a little differently than expected. The
2074     fourth argument (processed) is currently documented in Apple's
2075     documentation as: "On return, the length, in bytes, of the data actually
2076     written."
2077
2078     Now, one could interpret that as "written to the socket," but actually,
2079     it returns the amount of data that was written to a buffer internal to
2080     the SSLContextRef instead. So it's possible for SSLWrite() to return
2081     errSSLWouldBlock and a number of bytes "written" because those bytes were
2082     encrypted and written to a buffer, not to the socket.
2083
2084     So if this happens, then we need to keep calling SSLWrite() over and
2085     over again with no new data until it quits returning errSSLWouldBlock. */
2086
2087  /* Do we have buffered data to write from the last time we were called? */
2088  if(connssl->ssl_write_buffered_length) {
2089    /* Write the buffered data: */
2090    err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
2091    switch (err) {
2092      case noErr:
2093        /* processed is always going to be 0 because we didn't write to
2094           the buffer, so return how much was written to the socket */
2095        processed = connssl->ssl_write_buffered_length;
2096        connssl->ssl_write_buffered_length = 0UL;
2097        break;
2098      case errSSLWouldBlock: /* argh, try again */
2099        *curlcode = CURLE_AGAIN;
2100        return -1L;
2101      default:
2102        failf(conn->data, "SSLWrite() returned error %d", err);
2103        *curlcode = CURLE_SEND_ERROR;
2104        return -1L;
2105    }
2106  }
2107  else {
2108    /* We've got new data to write: */
2109    err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
2110    if(err != noErr) {
2111      switch (err) {
2112        case errSSLWouldBlock:
2113          /* Data was buffered but not sent, we have to tell the caller
2114             to try sending again, and remember how much was buffered */
2115          connssl->ssl_write_buffered_length = len;
2116          *curlcode = CURLE_AGAIN;
2117          return -1L;
2118        default:
2119          failf(conn->data, "SSLWrite() returned error %d", err);
2120          *curlcode = CURLE_SEND_ERROR;
2121          return -1L;
2122      }
2123    }
2124  }
2125  return (ssize_t)processed;
2126}
2127
2128static ssize_t darwinssl_recv(struct connectdata *conn,
2129                              int num,
2130                              char *buf,
2131                              size_t buffersize,
2132                              CURLcode *curlcode)
2133{
2134  /*struct SessionHandle *data = conn->data;*/
2135  struct ssl_connect_data *connssl = &conn->ssl[num];
2136  size_t processed = 0UL;
2137  OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
2138
2139  if(err != noErr) {
2140    switch (err) {
2141      case errSSLWouldBlock:  /* return how much we read (if anything) */
2142        if(processed)
2143          return (ssize_t)processed;
2144        *curlcode = CURLE_AGAIN;
2145        return -1L;
2146        break;
2147
2148      /* errSSLClosedGraceful - server gracefully shut down the SSL session
2149         errSSLClosedNoNotify - server hung up on us instead of sending a
2150           closure alert notice, read() is returning 0
2151         Either way, inform the caller that the server disconnected. */
2152      case errSSLClosedGraceful:
2153      case errSSLClosedNoNotify:
2154        *curlcode = CURLE_OK;
2155        return -1L;
2156        break;
2157
2158      default:
2159        failf(conn->data, "SSLRead() return error %d", err);
2160        *curlcode = CURLE_RECV_ERROR;
2161        return -1L;
2162        break;
2163    }
2164  }
2165  return (ssize_t)processed;
2166}
2167
2168#endif /* USE_DARWINSSL */
2169