1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 2012-2013, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012-2013, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ***************************************************************************/
25 * Source file for all iOS and Mac OS X SecureTransport-specific code for the
26 * TLS/SSL layer. No code but sslgen.c should ever call or use these functions.
29 #include "curl_setup.h"
37 #include <Security/Security.h>
38 #include <Security/SecureTransport.h>
39 #include <CoreFoundation/CoreFoundation.h>
40 #include <CommonCrypto/CommonDigest.h>
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.
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))
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 */
54 #define CURL_BUILD_IOS 0
55 #define CURL_BUILD_MAC 1
56 /* This is the maximum API level we are allowed to use when building: */
57 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
58 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
59 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
60 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
61 /* These macros mean "the following code is present to allow runtime backward
62 compatibility with at least this cat or earlier":
63 (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
64 environmental variable.) */
65 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
66 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
67 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
68 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
70 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
71 #define CURL_BUILD_IOS 1
72 #define CURL_BUILD_MAC 0
73 #define CURL_BUILD_MAC_10_5 0
74 #define CURL_BUILD_MAC_10_6 0
75 #define CURL_BUILD_MAC_10_7 0
76 #define CURL_BUILD_MAC_10_8 0
77 #define CURL_SUPPORT_MAC_10_5 0
78 #define CURL_SUPPORT_MAC_10_6 0
79 #define CURL_SUPPORT_MAC_10_7 0
80 #define CURL_SUPPORT_MAC_10_8 0
83 #error "The darwinssl back-end requires iOS or OS X."
84 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
87 #include <sys/sysctl.h>
88 #endif /* CURL_BUILD_MAC */
92 #include "inet_pton.h"
96 #include "curl_darwinssl.h"
98 #define _MPRINTF_REPLACE /* use our functions only */
99 #include <curl/mprintf.h>
101 #include "curl_memory.h"
102 /* The last #include file should be: */
103 #include "memdebug.h"
105 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
109 /* The following two functions were ripped from Apple sample code,
110 * with some modifications: */
111 static OSStatus SocketRead(SSLConnectionRef connection,
112 void *data, /* owned by
115 size_t *dataLength) /* IN/OUT */
117 size_t bytesToGo = *dataLength;
118 size_t initLen = bytesToGo;
119 UInt8 *currData = (UInt8 *)data;
120 /*int sock = *(int *)connection;*/
121 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
122 int sock = connssl->ssl_sockfd;
123 OSStatus rtn = noErr;
132 rrtn = read(sock, currData, bytesToGo);
134 /* this is guesswork... */
136 if(rrtn == 0) { /* EOF = server hung up */
137 /* the framework will turn this into errSSLClosedNoNotify */
138 rtn = errSSLClosedGraceful;
140 else /* do the switch */
143 /* connection closed */
144 rtn = errSSLClosedGraceful;
147 rtn = errSSLClosedAbort;
150 rtn = errSSLWouldBlock;
151 connssl->ssl_direction = false;
162 bytesToGo -= bytesRead;
163 currData += bytesRead;
166 /* filled buffer with incoming data, done */
170 *dataLength = initLen - bytesToGo;
175 static OSStatus SocketWrite(SSLConnectionRef connection,
177 size_t *dataLength) /* IN/OUT */
179 size_t bytesSent = 0;
180 /*int sock = *(int *)connection;*/
181 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
182 int sock = connssl->ssl_sockfd;
184 size_t dataLen = *dataLength;
185 const UInt8 *dataPtr = (UInt8 *)data;
193 (char*)dataPtr + bytesSent,
194 dataLen - bytesSent);
195 } while((length > 0) &&
196 ( (bytesSent += length) < dataLen) );
200 if(theErr == EAGAIN) {
201 ortn = errSSLWouldBlock;
202 connssl->ssl_direction = true;
211 *dataLength = bytesSent;
215 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
217 /* SSL version 3.0 */
218 case SSL_RSA_WITH_NULL_MD5:
219 return "SSL_RSA_WITH_NULL_MD5";
221 case SSL_RSA_WITH_NULL_SHA:
222 return "SSL_RSA_WITH_NULL_SHA";
224 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
225 return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
227 case SSL_RSA_WITH_RC4_128_MD5:
228 return "SSL_RSA_WITH_RC4_128_MD5";
230 case SSL_RSA_WITH_RC4_128_SHA:
231 return "SSL_RSA_WITH_RC4_128_SHA";
233 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
234 return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
236 case SSL_RSA_WITH_IDEA_CBC_SHA:
237 return "SSL_RSA_WITH_IDEA_CBC_SHA";
239 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
240 return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
242 case SSL_RSA_WITH_DES_CBC_SHA:
243 return "SSL_RSA_WITH_DES_CBC_SHA";
245 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
246 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
248 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
249 return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
251 case SSL_DH_DSS_WITH_DES_CBC_SHA:
252 return "SSL_DH_DSS_WITH_DES_CBC_SHA";
254 case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
255 return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
257 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
258 return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
260 case SSL_DH_RSA_WITH_DES_CBC_SHA:
261 return "SSL_DH_RSA_WITH_DES_CBC_SHA";
263 case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
264 return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
266 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
267 return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
269 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
270 return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
272 case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
273 return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
275 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
276 return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
278 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
279 return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
281 case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
282 return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
284 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
285 return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
287 case SSL_DH_anon_WITH_RC4_128_MD5:
288 return "SSL_DH_anon_WITH_RC4_128_MD5";
290 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
291 return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
293 case SSL_DH_anon_WITH_DES_CBC_SHA:
294 return "SSL_DH_anon_WITH_DES_CBC_SHA";
296 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
297 return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
299 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
300 return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
302 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
303 return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
305 /* TLS 1.0 with AES (RFC 3268)
306 (Apparently these are used in SSLv3 implementations as well.) */
307 case TLS_RSA_WITH_AES_128_CBC_SHA:
308 return "TLS_RSA_WITH_AES_128_CBC_SHA";
310 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
311 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
313 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
314 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
316 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
317 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
319 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
320 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
322 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
323 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
325 case TLS_RSA_WITH_AES_256_CBC_SHA:
326 return "TLS_RSA_WITH_AES_256_CBC_SHA";
328 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
329 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
331 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
332 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
334 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
335 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
337 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
338 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
340 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
341 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
343 /* SSL version 2.0 */
344 case SSL_RSA_WITH_RC2_CBC_MD5:
345 return "SSL_RSA_WITH_RC2_CBC_MD5";
347 case SSL_RSA_WITH_IDEA_CBC_MD5:
348 return "SSL_RSA_WITH_IDEA_CBC_MD5";
350 case SSL_RSA_WITH_DES_CBC_MD5:
351 return "SSL_RSA_WITH_DES_CBC_MD5";
353 case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
354 return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
357 return "SSL_NULL_WITH_NULL_NULL";
360 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
362 /* TLS 1.0 with AES (RFC 3268) */
363 case TLS_RSA_WITH_AES_128_CBC_SHA:
364 return "TLS_RSA_WITH_AES_128_CBC_SHA";
366 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
367 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
369 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
370 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
372 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
373 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
375 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
376 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
378 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
379 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
381 case TLS_RSA_WITH_AES_256_CBC_SHA:
382 return "TLS_RSA_WITH_AES_256_CBC_SHA";
384 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
385 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
387 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
388 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
390 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
391 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
393 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
394 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
396 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
397 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
399 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
400 /* TLS 1.0 with ECDSA (RFC 4492) */
401 case TLS_ECDH_ECDSA_WITH_NULL_SHA:
402 return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
404 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
405 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
407 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
408 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
410 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
411 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
413 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
414 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
416 case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
417 return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
419 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
420 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
422 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
423 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
425 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
426 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
428 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
429 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
431 case TLS_ECDH_RSA_WITH_NULL_SHA:
432 return "TLS_ECDH_RSA_WITH_NULL_SHA";
434 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
435 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
437 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
438 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
440 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
441 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
443 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
444 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
446 case TLS_ECDHE_RSA_WITH_NULL_SHA:
447 return "TLS_ECDHE_RSA_WITH_NULL_SHA";
449 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
450 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
452 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
453 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
455 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
456 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
458 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
459 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
461 case TLS_ECDH_anon_WITH_NULL_SHA:
462 return "TLS_ECDH_anon_WITH_NULL_SHA";
464 case TLS_ECDH_anon_WITH_RC4_128_SHA:
465 return "TLS_ECDH_anon_WITH_RC4_128_SHA";
467 case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
468 return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
470 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
471 return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
473 case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
474 return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
476 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
477 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
478 /* TLS 1.2 (RFC 5246) */
479 case TLS_RSA_WITH_NULL_MD5:
480 return "TLS_RSA_WITH_NULL_MD5";
482 case TLS_RSA_WITH_NULL_SHA:
483 return "TLS_RSA_WITH_NULL_SHA";
485 case TLS_RSA_WITH_RC4_128_MD5:
486 return "TLS_RSA_WITH_RC4_128_MD5";
488 case TLS_RSA_WITH_RC4_128_SHA:
489 return "TLS_RSA_WITH_RC4_128_SHA";
491 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
492 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
494 case TLS_RSA_WITH_NULL_SHA256:
495 return "TLS_RSA_WITH_NULL_SHA256";
497 case TLS_RSA_WITH_AES_128_CBC_SHA256:
498 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
500 case TLS_RSA_WITH_AES_256_CBC_SHA256:
501 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
503 case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
504 return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
506 case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
507 return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
509 case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
510 return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
512 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
513 return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
515 case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
516 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
518 case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
519 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
521 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
522 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
524 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
525 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
527 case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
528 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
530 case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
531 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
533 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
534 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
536 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
537 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
539 case TLS_DH_anon_WITH_RC4_128_MD5:
540 return "TLS_DH_anon_WITH_RC4_128_MD5";
542 case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
543 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
545 case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
546 return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
548 case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
549 return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
551 /* TLS 1.2 with AES GCM (RFC 5288) */
552 case TLS_RSA_WITH_AES_128_GCM_SHA256:
553 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
555 case TLS_RSA_WITH_AES_256_GCM_SHA384:
556 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
558 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
559 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
561 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
562 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
564 case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
565 return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
567 case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
568 return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
570 case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
571 return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
573 case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
574 return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
576 case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
577 return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
579 case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
580 return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
582 case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
583 return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
585 case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
586 return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
588 /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
589 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
590 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
592 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
593 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
595 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
596 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
598 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
599 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
601 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
602 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
604 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
605 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
607 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
608 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
610 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
611 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
613 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
614 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
616 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
617 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
619 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
620 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
622 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
623 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
625 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
626 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
628 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
629 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
631 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
632 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
634 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
635 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
637 case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
638 return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
641 case SSL_RSA_WITH_NULL_MD5:
642 return "TLS_RSA_WITH_NULL_MD5";
644 case SSL_RSA_WITH_NULL_SHA:
645 return "TLS_RSA_WITH_NULL_SHA";
647 case SSL_RSA_WITH_RC4_128_MD5:
648 return "TLS_RSA_WITH_RC4_128_MD5";
650 case SSL_RSA_WITH_RC4_128_SHA:
651 return "TLS_RSA_WITH_RC4_128_SHA";
653 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
654 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
656 case SSL_DH_anon_WITH_RC4_128_MD5:
657 return "TLS_DH_anon_WITH_RC4_128_MD5";
659 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
660 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
662 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
664 return "TLS_NULL_WITH_NULL_NULL";
668 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
672 size_t os_version_len;
673 char *os_version_major, *os_version_minor/*, *os_version_point*/;
675 /* Get the Darwin kernel version from the kernel using sysctl(): */
677 mib[1] = KERN_OSRELEASE;
678 if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
680 os_version = malloc(os_version_len*sizeof(char));
683 if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
688 /* Parse the version: */
689 os_version_major = strtok(os_version, ".");
690 os_version_minor = strtok(NULL, ".");
691 /*os_version_point = strtok(NULL, ".");*/
692 *major = atoi(os_version_major);
693 *minor = atoi(os_version_minor);
696 #endif /* CURL_BUILD_MAC */
698 /* Apple provides a myriad of ways of getting information about a certificate
699 into a string. Some aren't available under iOS or newer cats. So here's
700 a unified function for getting a string describing the certificate that
701 ought to work in all cats starting with Leopard. */
702 CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
704 CFStringRef server_cert_summary = CFSTR("(null)");
707 /* iOS: There's only one way to do this. */
708 server_cert_summary = SecCertificateCopySubjectSummary(cert);
710 #if CURL_BUILD_MAC_10_7
711 /* Lion & later: Get the long description if we can. */
712 if(SecCertificateCopyLongDescription != NULL)
713 server_cert_summary =
714 SecCertificateCopyLongDescription(NULL, cert, NULL);
716 #endif /* CURL_BUILD_MAC_10_7 */
717 #if CURL_BUILD_MAC_10_6
718 /* Snow Leopard: Get the certificate summary. */
719 if(SecCertificateCopySubjectSummary != NULL)
720 server_cert_summary = SecCertificateCopySubjectSummary(cert);
722 #endif /* CURL_BUILD_MAC_10_6 */
723 /* Leopard is as far back as we go... */
724 (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
725 #endif /* CURL_BUILD_IOS */
726 return server_cert_summary;
729 #if CURL_SUPPORT_MAC_10_7
730 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
731 deprecation warnings, so let's not compile this unless it's necessary: */
732 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
733 SecIdentityRef *out_c_a_k)
735 OSStatus status = errSecItemNotFound;
736 SecKeychainAttributeList attr_list;
737 SecKeychainAttribute attr;
738 SecKeychainSearchRef search = NULL;
739 SecCertificateRef cert = NULL;
741 /* Set up the attribute list: */
742 attr_list.count = 1L;
743 attr_list.attr = &attr;
745 /* Set up our lone search criterion: */
746 attr.tag = kSecLabelItemAttr;
748 attr.length = (UInt32)strlen(label);
750 /* Start searching: */
751 status = SecKeychainSearchCreateFromAttributes(NULL,
752 kSecCertificateItemClass,
755 if(status == noErr) {
756 status = SecKeychainSearchCopyNext(search,
757 (SecKeychainItemRef *)&cert);
758 if(status == noErr && cert) {
759 /* If we found a certificate, does it have a private key? */
760 status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
769 #endif /* CURL_SUPPORT_MAC_10_7 */
771 static OSStatus CopyIdentityWithLabel(char *label,
772 SecIdentityRef *out_cert_and_key)
774 OSStatus status = errSecItemNotFound;
776 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
777 /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
778 kSecClassIdentity was introduced in Lion. If both exist, let's use them
779 to find the certificate. */
780 if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
783 CFDictionaryRef query_dict;
784 CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
785 kCFStringEncodingUTF8);
787 /* Set up our search criteria and expected results: */
788 values[0] = kSecClassIdentity; /* we want a certificate and a key */
790 values[1] = kCFBooleanTrue; /* we want a reference */
791 keys[1] = kSecReturnRef;
792 values[2] = kSecMatchLimitOne; /* one is enough, thanks */
793 keys[2] = kSecMatchLimit;
794 /* identity searches need a SecPolicyRef in order to work */
795 values[3] = SecPolicyCreateSSL(false, label_cf);
796 keys[3] = kSecMatchPolicy;
797 query_dict = CFDictionaryCreate(NULL, (const void **)keys,
798 (const void **)values, 4L,
799 &kCFCopyStringDictionaryKeyCallBacks,
800 &kCFTypeDictionaryValueCallBacks);
801 CFRelease(values[3]);
804 /* Do we have a match? */
805 status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
806 CFRelease(query_dict);
809 #if CURL_SUPPORT_MAC_10_7
810 /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
811 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
812 #endif /* CURL_SUPPORT_MAC_10_7 */
814 #elif CURL_SUPPORT_MAC_10_7
815 /* For developers building on older cats, we have no choice but to fall back
816 to SecKeychainSearch. */
817 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
818 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
822 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
825 struct SessionHandle *data = conn->data;
826 curl_socket_t sockfd = conn->sock[sockindex];
827 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
829 struct in6_addr addr;
832 #endif /* ENABLE_IPV6 */
833 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
834 SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
836 size_t ssl_sessionid_len;
837 OSStatus err = noErr;
839 int darwinver_maj = 0, darwinver_min = 0;
841 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
842 #endif /* CURL_BUILD_MAC */
844 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
845 if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
847 CFRelease(connssl->ssl_ctx);
848 connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
849 if(!connssl->ssl_ctx) {
850 failf(data, "SSL: couldn't create a context!");
851 return CURLE_OUT_OF_MEMORY;
855 /* The old ST API does not exist under iOS, so don't compile it: */
856 #if CURL_SUPPORT_MAC_10_8
858 (void)SSLDisposeContext(connssl->ssl_ctx);
859 err = SSLNewContext(false, &(connssl->ssl_ctx));
861 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
862 return CURLE_OUT_OF_MEMORY;
864 #endif /* CURL_SUPPORT_MAC_10_8 */
868 (void)SSLDisposeContext(connssl->ssl_ctx);
869 err = SSLNewContext(false, &(connssl->ssl_ctx));
871 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
872 return CURLE_OUT_OF_MEMORY;
874 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
875 connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
877 /* check to see if we've been told to use an explicit SSL/TLS version */
878 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
879 if(SSLSetProtocolVersionMax != NULL) {
880 switch(data->set.ssl.version) {
881 case CURL_SSLVERSION_DEFAULT: default:
882 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
883 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
885 case CURL_SSLVERSION_TLSv1:
886 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
887 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
889 case CURL_SSLVERSION_SSLv3:
890 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
891 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
893 case CURL_SSLVERSION_SSLv2:
894 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
896 failf(data, "Your version of the OS does not support SSLv2");
897 return CURLE_SSL_CONNECT_ERROR;
899 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
903 #if CURL_SUPPORT_MAC_10_8
904 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
907 switch (data->set.ssl.version) {
908 case CURL_SSLVERSION_DEFAULT: default:
909 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
912 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
915 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
918 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
922 case CURL_SSLVERSION_TLSv1:
923 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
926 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
929 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
933 case CURL_SSLVERSION_SSLv3:
934 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
938 case CURL_SSLVERSION_SSLv2:
939 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
943 failf(data, "Your version of the OS does not support SSLv2");
944 return CURLE_SSL_CONNECT_ERROR;
948 #endif /* CURL_SUPPORT_MAC_10_8 */
951 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
952 switch(data->set.ssl.version) {
954 case CURL_SSLVERSION_DEFAULT:
955 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
958 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
962 case CURL_SSLVERSION_TLSv1:
963 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
967 case CURL_SSLVERSION_SSLv2:
968 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
972 failf(data, "Your version of the OS does not support SSLv2");
973 return CURLE_SSL_CONNECT_ERROR;
976 case CURL_SSLVERSION_SSLv3:
977 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
982 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
984 if(data->set.str[STRING_KEY]) {
985 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
986 "Transport. The private key must be in the Keychain.\n");
989 if(data->set.str[STRING_CERT]) {
990 SecIdentityRef cert_and_key = NULL;
992 /* User wants to authenticate with a client cert. Look for it: */
993 err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
995 SecCertificateRef cert = NULL;
996 CFTypeRef certs_c[1];
999 /* If we found one, print it out: */
1000 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1002 CFStringRef cert_summary = CopyCertSubject(cert);
1003 char cert_summary_c[128];
1006 memset(cert_summary_c, 0, 128);
1007 if(CFStringGetCString(cert_summary,
1010 kCFStringEncodingUTF8)) {
1011 infof(data, "Client certificate: %s\n", cert_summary_c);
1013 CFRelease(cert_summary);
1017 certs_c[0] = cert_and_key;
1018 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1019 &kCFTypeArrayCallBacks);
1020 err = SSLSetCertificate(connssl->ssl_ctx, certs);
1024 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1025 return CURLE_SSL_CERTPROBLEM;
1027 CFRelease(cert_and_key);
1030 failf(data, "SSL: Can't find the certificate \"%s\" and its private key "
1031 "in the Keychain.", data->set.str[STRING_CERT]);
1032 return CURLE_SSL_CERTPROBLEM;
1036 /* SSL always tries to verify the peer, this only says whether it should
1037 * fail to connect if the verification fails, or if it should continue
1038 * anyway. In the latter case the result of the verification is checked with
1039 * SSL_get_verify_result() below. */
1040 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1041 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1042 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1043 works, it doesn't work as expected under Snow Leopard or Lion.
1044 So we need to call SSLSetEnableCertVerify() on those older cats in order
1045 to disable certificate validation if the user turned that off.
1046 (SecureTransport will always validate the certificate chain by
1048 /* (Note: Darwin 12.x.x is Mountain Lion.) */
1050 if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
1052 if(SSLSetSessionOption != NULL) {
1053 #endif /* CURL_BUILD_MAC */
1054 err = SSLSetSessionOption(connssl->ssl_ctx,
1055 kSSLSessionOptionBreakOnServerAuth,
1056 data->set.ssl.verifypeer?false:true);
1058 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1059 return CURLE_SSL_CONNECT_ERROR;
1063 #if CURL_SUPPORT_MAC_10_8
1064 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1065 data->set.ssl.verifypeer?true:false);
1067 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1068 return CURLE_SSL_CONNECT_ERROR;
1070 #endif /* CURL_SUPPORT_MAC_10_8 */
1073 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1074 data->set.ssl.verifypeer?true:false);
1076 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1077 return CURLE_SSL_CONNECT_ERROR;
1079 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1081 /* If this is a domain name and not an IP address, then configure SNI.
1082 * Also: the verifyhost setting influences SNI usage */
1083 /* If this is a domain name and not an IP address, then configure SNI: */
1084 if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
1086 (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
1088 data->set.ssl.verifyhost) {
1089 err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1090 strlen(conn->host.name));
1092 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1097 /* Disable cipher suites that ST supports but are not safe. These ciphers
1098 are unlikely to be used in any case since ST gives other ciphers a much
1099 higher priority, but it's probably better that we not connect at all than
1100 to give the user a false sense of security if the server only supports
1101 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1102 (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1103 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1104 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1105 if(all_ciphers && allowed_ciphers &&
1106 SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1107 &all_ciphers_count) == noErr) {
1108 for(i = 0UL ; i < all_ciphers_count ; i++) {
1110 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1111 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1112 Work around the problem here by disabling those ciphers if we are
1113 running in an affected version of OS X. */
1114 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1115 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1118 #endif /* CURL_BUILD_MAC */
1119 switch(all_ciphers[i]) {
1120 /* Disable NULL ciphersuites: */
1121 case SSL_NULL_WITH_NULL_NULL:
1122 case SSL_RSA_WITH_NULL_MD5:
1123 case SSL_RSA_WITH_NULL_SHA:
1124 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1125 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1126 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1127 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1128 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1129 /* Disable anonymous ciphersuites: */
1130 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1131 case SSL_DH_anon_WITH_RC4_128_MD5:
1132 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1133 case SSL_DH_anon_WITH_DES_CBC_SHA:
1134 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1135 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1136 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1137 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1138 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1139 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1140 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1141 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1142 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1143 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1144 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1145 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1146 /* Disable weak key ciphersuites: */
1147 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1148 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1149 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1150 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1151 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1152 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1153 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1154 case SSL_RSA_WITH_DES_CBC_SHA:
1155 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1156 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1157 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1158 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1160 case SSL_RSA_WITH_IDEA_CBC_SHA:
1161 case SSL_RSA_WITH_IDEA_CBC_MD5:
1163 default: /* enable everything else */
1164 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1168 err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1169 allowed_ciphers_count);
1171 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1172 return CURLE_SSL_CONNECT_ERROR;
1176 Curl_safefree(all_ciphers);
1177 Curl_safefree(allowed_ciphers);
1178 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1179 return CURLE_OUT_OF_MEMORY;
1181 Curl_safefree(all_ciphers);
1182 Curl_safefree(allowed_ciphers);
1184 /* Check if there's a cached ID we can/should use here! */
1185 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1186 &ssl_sessionid_len)) {
1187 /* we got a session id, use it! */
1188 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1190 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1191 return CURLE_SSL_CONNECT_ERROR;
1193 /* Informational message */
1194 infof(data, "SSL re-using session ID\n");
1196 /* If there isn't one, then let's make one up! This has to be done prior
1197 to starting the handshake. */
1201 ssl_sessionid = malloc(256*sizeof(char));
1202 ssl_sessionid_len = snprintf(ssl_sessionid, 256, "curl:%s:%hu",
1203 conn->host.name, conn->remote_port);
1204 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1206 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1207 return CURLE_SSL_CONNECT_ERROR;
1209 retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1210 if(retcode!= CURLE_OK) {
1211 failf(data, "failed to store ssl session");
1216 err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1218 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1219 return CURLE_SSL_CONNECT_ERROR;
1222 /* pass the raw socket into the SSL layers */
1223 /* We need to store the FD in a constant memory address, because
1224 * SSLSetConnection() will not copy that address. I've found that
1225 * conn->sock[sockindex] may change on its own. */
1226 connssl->ssl_sockfd = sockfd;
1227 err = SSLSetConnection(connssl->ssl_ctx, connssl);
1229 failf(data, "SSL: SSLSetConnection() failed: %d", err);
1230 return CURLE_SSL_CONNECT_ERROR;
1233 connssl->connecting_state = ssl_connect_2;
1238 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1240 struct SessionHandle *data = conn->data;
1241 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1243 SSLCipherSuite cipher;
1244 SSLProtocol protocol = 0;
1246 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1247 || ssl_connect_2_reading == connssl->connecting_state
1248 || ssl_connect_2_writing == connssl->connecting_state);
1250 /* Here goes nothing: */
1251 err = SSLHandshake(connssl->ssl_ctx);
1255 case errSSLWouldBlock: /* they're not done with us yet */
1256 connssl->connecting_state = connssl->ssl_direction ?
1257 ssl_connect_2_writing : ssl_connect_2_reading;
1260 /* The below is errSSLServerAuthCompleted; it's not defined in
1261 Leopard's headers */
1263 /* the documentation says we need to call SSLHandshake() again */
1264 return darwinssl_connect_step2(conn, sockindex);
1266 /* These are all certificate problems with the server: */
1267 case errSSLXCertChainInvalid:
1268 failf(data, "SSL certificate problem: Invalid certificate chain");
1269 return CURLE_SSL_CACERT;
1270 case errSSLUnknownRootCert:
1271 failf(data, "SSL certificate problem: Untrusted root certificate");
1272 return CURLE_SSL_CACERT;
1273 case errSSLNoRootCert:
1274 failf(data, "SSL certificate problem: No root certificate");
1275 return CURLE_SSL_CACERT;
1276 case errSSLCertExpired:
1277 failf(data, "SSL certificate problem: Certificate chain had an "
1278 "expired certificate");
1279 return CURLE_SSL_CACERT;
1281 failf(data, "SSL certificate problem: Couldn't understand the server "
1282 "certificate format");
1283 return CURLE_SSL_CONNECT_ERROR;
1285 /* These are all certificate problems with the client: */
1286 case errSecAuthFailed:
1287 failf(data, "SSL authentication failed");
1288 return CURLE_SSL_CONNECT_ERROR;
1289 case errSSLPeerHandshakeFail:
1290 failf(data, "SSL peer handshake failed, the server most likely "
1291 "requires a client certificate to connect");
1292 return CURLE_SSL_CONNECT_ERROR;
1293 case errSSLPeerUnknownCA:
1294 failf(data, "SSL server rejected the client certificate due to "
1295 "the certificate being signed by an unknown certificate "
1297 return CURLE_SSL_CONNECT_ERROR;
1299 /* This error is raised if the server's cert didn't match the server's
1301 case errSSLHostNameMismatch:
1302 failf(data, "SSL certificate peer verification failed, the "
1303 "certificate did not match \"%s\"\n", conn->host.dispname);
1304 return CURLE_PEER_FAILED_VERIFICATION;
1306 /* Generic handshake errors: */
1307 case errSSLConnectionRefused:
1308 failf(data, "Server dropped the connection during the SSL handshake");
1309 return CURLE_SSL_CONNECT_ERROR;
1310 case errSSLClosedAbort:
1311 failf(data, "Server aborted the SSL handshake");
1312 return CURLE_SSL_CONNECT_ERROR;
1313 case errSSLNegotiation:
1314 failf(data, "Could not negotiate an SSL cipher suite with the server");
1315 return CURLE_SSL_CONNECT_ERROR;
1316 /* Sometimes paramErr happens with buggy ciphers: */
1317 case paramErr: case errSSLInternal:
1318 failf(data, "Internal SSL engine error encountered during the "
1320 return CURLE_SSL_CONNECT_ERROR;
1321 case errSSLFatalAlert:
1322 failf(data, "Fatal SSL engine error encountered during the SSL "
1324 return CURLE_SSL_CONNECT_ERROR;
1326 failf(data, "Unknown SSL protocol error in connection to %s:%d",
1327 conn->host.name, err);
1328 return CURLE_SSL_CONNECT_ERROR;
1332 /* we have been connected fine, we're not waiting for anything else. */
1333 connssl->connecting_state = ssl_connect_3;
1335 /* Informational message */
1336 (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1337 (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1340 infof(data, "SSL 2.0 connection using %s\n",
1341 SSLCipherNameForNumber(cipher));
1344 infof(data, "SSL 3.0 connection using %s\n",
1345 SSLCipherNameForNumber(cipher));
1348 infof(data, "TLS 1.0 connection using %s\n",
1349 TLSCipherNameForNumber(cipher));
1351 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1352 case kTLSProtocol11:
1353 infof(data, "TLS 1.1 connection using %s\n",
1354 TLSCipherNameForNumber(cipher));
1356 case kTLSProtocol12:
1357 infof(data, "TLS 1.2 connection using %s\n",
1358 TLSCipherNameForNumber(cipher));
1362 infof(data, "Unknown protocol connection\n");
1371 darwinssl_connect_step3(struct connectdata *conn,
1374 struct SessionHandle *data = conn->data;
1375 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1376 CFStringRef server_cert_summary;
1377 char server_cert_summary_c[128];
1378 CFArrayRef server_certs = NULL;
1379 SecCertificateRef server_cert;
1382 SecTrustRef trust = NULL;
1384 /* There is no step 3!
1385 * Well, okay, if verbose mode is on, let's print the details of the
1386 * server certificates. */
1387 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1389 #pragma unused(server_certs)
1390 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1391 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1392 a null trust, so be on guard for that: */
1393 if(err == noErr && trust) {
1394 count = SecTrustGetCertificateCount(trust);
1395 for(i = 0L ; i < count ; i++) {
1396 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1397 server_cert_summary = CopyCertSubject(server_cert);
1398 memset(server_cert_summary_c, 0, 128);
1399 if(CFStringGetCString(server_cert_summary,
1400 server_cert_summary_c,
1402 kCFStringEncodingUTF8)) {
1403 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1405 CFRelease(server_cert_summary);
1410 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
1411 The function SecTrustGetCertificateAtIndex() is officially present
1412 in Lion, but it is unfortunately also present in Snow Leopard as
1413 private API and doesn't work as expected. So we have to look for
1414 a different symbol to make sure this code is only executed under
1416 if(SecTrustEvaluateAsync != NULL) {
1417 #pragma unused(server_certs)
1418 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1419 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1420 a null trust, so be on guard for that: */
1421 if(err == noErr && trust) {
1422 count = SecTrustGetCertificateCount(trust);
1423 for(i = 0L ; i < count ; i++) {
1424 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1425 server_cert_summary = CopyCertSubject(server_cert);
1426 memset(server_cert_summary_c, 0, 128);
1427 if(CFStringGetCString(server_cert_summary,
1428 server_cert_summary_c,
1430 kCFStringEncodingUTF8)) {
1431 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1433 CFRelease(server_cert_summary);
1439 #if CURL_SUPPORT_MAC_10_8
1440 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1441 /* Just in case SSLCopyPeerCertificates() returns null too... */
1442 if(err == noErr && server_certs) {
1443 count = CFArrayGetCount(server_certs);
1444 for(i = 0L ; i < count ; i++) {
1445 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
1448 server_cert_summary = CopyCertSubject(server_cert);
1449 memset(server_cert_summary_c, 0, 128);
1450 if(CFStringGetCString(server_cert_summary,
1451 server_cert_summary_c,
1453 kCFStringEncodingUTF8)) {
1454 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1456 CFRelease(server_cert_summary);
1458 CFRelease(server_certs);
1460 #endif /* CURL_SUPPORT_MAC_10_8 */
1462 #endif /* CURL_BUILD_IOS */
1464 #pragma unused(trust)
1465 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1467 count = CFArrayGetCount(server_certs);
1468 for(i = 0L ; i < count ; i++) {
1469 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
1470 server_cert_summary = CopyCertSubject(server_cert);
1471 memset(server_cert_summary_c, 0, 128);
1472 if(CFStringGetCString(server_cert_summary,
1473 server_cert_summary_c,
1475 kCFStringEncodingUTF8)) {
1476 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1478 CFRelease(server_cert_summary);
1480 CFRelease(server_certs);
1482 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1484 connssl->connecting_state = ssl_connect_done;
1488 static Curl_recv darwinssl_recv;
1489 static Curl_send darwinssl_send;
1492 darwinssl_connect_common(struct connectdata *conn,
1498 struct SessionHandle *data = conn->data;
1499 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1500 curl_socket_t sockfd = conn->sock[sockindex];
1504 /* check if the connection has already been established */
1505 if(ssl_connection_complete == connssl->state) {
1510 if(ssl_connect_1==connssl->connecting_state) {
1511 /* Find out how much more time we're allowed */
1512 timeout_ms = Curl_timeleft(data, NULL, TRUE);
1514 if(timeout_ms < 0) {
1515 /* no need to continue if time already is up */
1516 failf(data, "SSL connection timeout");
1517 return CURLE_OPERATION_TIMEDOUT;
1519 retcode = darwinssl_connect_step1(conn, sockindex);
1524 while(ssl_connect_2 == connssl->connecting_state ||
1525 ssl_connect_2_reading == connssl->connecting_state ||
1526 ssl_connect_2_writing == connssl->connecting_state) {
1528 /* check allowed time left */
1529 timeout_ms = Curl_timeleft(data, NULL, TRUE);
1531 if(timeout_ms < 0) {
1532 /* no need to continue if time already is up */
1533 failf(data, "SSL connection timeout");
1534 return CURLE_OPERATION_TIMEDOUT;
1537 /* if ssl is expecting something, check if it's available. */
1538 if(connssl->connecting_state == ssl_connect_2_reading
1539 || connssl->connecting_state == ssl_connect_2_writing) {
1541 curl_socket_t writefd = ssl_connect_2_writing ==
1542 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1543 curl_socket_t readfd = ssl_connect_2_reading ==
1544 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1546 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
1549 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1550 return CURLE_SSL_CONNECT_ERROR;
1552 else if(0 == what) {
1559 failf(data, "SSL connection timeout");
1560 return CURLE_OPERATION_TIMEDOUT;
1563 /* socket is readable or writable */
1566 /* Run transaction, and return to the caller if it failed or if this
1567 * connection is done nonblocking and this loop would execute again. This
1568 * permits the owner of a multi handle to abort a connection attempt
1569 * before step2 has completed while ensuring that a client using select()
1570 * or epoll() will always have a valid fdset to wait on.
1572 retcode = darwinssl_connect_step2(conn, sockindex);
1573 if(retcode || (nonblocking &&
1574 (ssl_connect_2 == connssl->connecting_state ||
1575 ssl_connect_2_reading == connssl->connecting_state ||
1576 ssl_connect_2_writing == connssl->connecting_state)))
1579 } /* repeat step2 until all transactions are done. */
1582 if(ssl_connect_3==connssl->connecting_state) {
1583 retcode = darwinssl_connect_step3(conn, sockindex);
1588 if(ssl_connect_done==connssl->connecting_state) {
1589 connssl->state = ssl_connection_complete;
1590 conn->recv[sockindex] = darwinssl_recv;
1591 conn->send[sockindex] = darwinssl_send;
1597 /* Reset our connect state machine */
1598 connssl->connecting_state = ssl_connect_1;
1604 Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
1608 return darwinssl_connect_common(conn, sockindex, TRUE, done);
1612 Curl_darwinssl_connect(struct connectdata *conn,
1618 retcode = darwinssl_connect_common(conn, sockindex, FALSE, &done);
1628 void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
1630 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1632 if(connssl->ssl_ctx) {
1633 (void)SSLClose(connssl->ssl_ctx);
1634 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1635 if(SSLCreateContext != NULL)
1636 CFRelease(connssl->ssl_ctx);
1637 #if CURL_SUPPORT_MAC_10_8
1639 (void)SSLDisposeContext(connssl->ssl_ctx);
1640 #endif /* CURL_SUPPORT_MAC_10_8 */
1642 (void)SSLDisposeContext(connssl->ssl_ctx);
1643 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1644 connssl->ssl_ctx = NULL;
1646 connssl->ssl_sockfd = 0;
1649 void Curl_darwinssl_close_all(struct SessionHandle *data)
1651 /* SecureTransport doesn't separate sessions from contexts, so... */
1655 int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
1657 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1658 struct SessionHandle *data = conn->data;
1664 if(!connssl->ssl_ctx)
1667 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
1670 Curl_darwinssl_close(conn, sockindex);
1674 what = Curl_socket_ready(conn->sock[sockindex],
1675 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
1679 /* anything that gets here is fatally bad */
1680 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1685 if(!what) { /* timeout */
1686 failf(data, "SSL shutdown timeout");
1690 /* Something to read, let's do it and hope that it is the close
1691 notify alert from the server. No way to SSL_Read now, so use read(). */
1693 nread = read(conn->sock[sockindex], buf, sizeof(buf));
1696 failf(data, "read: %s", strerror(errno));
1703 what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
1709 void Curl_darwinssl_session_free(void *ptr)
1711 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
1712 cached session ID inside the Security framework. There is a private
1713 function that does this, but I don't want to have to explain to you why I
1714 got your application rejected from the App Store due to the use of a
1715 private API, so the best we can do is free up our own char array that we
1716 created way back in darwinssl_connect_step1... */
1720 size_t Curl_darwinssl_version(char *buffer, size_t size)
1722 return snprintf(buffer, size, "SecureTransport");
1726 * This function uses SSLGetSessionState to determine connection status.
1729 * 1 means the connection is still in place
1730 * 0 means the connection has been closed
1731 * -1 means the connection status is unknown
1733 int Curl_darwinssl_check_cxn(struct connectdata *conn)
1735 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1737 SSLSessionState state;
1739 if(connssl->ssl_ctx) {
1740 err = SSLGetSessionState(connssl->ssl_ctx, &state);
1742 return state == kSSLConnected || state == kSSLHandshake;
1748 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
1751 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
1755 if(connssl->ssl_ctx) { /* SSL is in use */
1756 err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
1758 return buffer > 0UL;
1765 void Curl_darwinssl_random(struct SessionHandle *data,
1766 unsigned char *entropy,
1769 /* arc4random_buf() isn't available on cats older than Lion, so let's
1770 do this manually for the benefit of the older cats. */
1772 u_int32_t random_number = 0;
1774 for(i = 0 ; i < length ; i++) {
1775 if(i % sizeof(u_int32_t) == 0)
1776 random_number = arc4random();
1777 entropy[i] = random_number & 0xFF;
1778 random_number >>= 8;
1780 i = random_number = 0;
1784 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
1786 unsigned char *md5sum, /* output */
1790 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
1793 static ssize_t darwinssl_send(struct connectdata *conn,
1799 /*struct SessionHandle *data = conn->data;*/
1800 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1801 size_t processed = 0UL;
1804 /* The SSLWrite() function works a little differently than expected. The
1805 fourth argument (processed) is currently documented in Apple's
1806 documentation as: "On return, the length, in bytes, of the data actually
1809 Now, one could interpret that as "written to the socket," but actually,
1810 it returns the amount of data that was written to a buffer internal to
1811 the SSLContextRef instead. So it's possible for SSLWrite() to return
1812 errSSLWouldBlock and a number of bytes "written" because those bytes were
1813 encrypted and written to a buffer, not to the socket.
1815 So if this happens, then we need to keep calling SSLWrite() over and
1816 over again with no new data until it quits returning errSSLWouldBlock. */
1818 /* Do we have buffered data to write from the last time we were called? */
1819 if(connssl->ssl_write_buffered_length) {
1820 /* Write the buffered data: */
1821 err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
1824 /* processed is always going to be 0 because we didn't write to
1825 the buffer, so return how much was written to the socket */
1826 processed = connssl->ssl_write_buffered_length;
1827 connssl->ssl_write_buffered_length = 0UL;
1829 case errSSLWouldBlock: /* argh, try again */
1830 *curlcode = CURLE_AGAIN;
1833 failf(conn->data, "SSLWrite() returned error %d", err);
1834 *curlcode = CURLE_SEND_ERROR;
1839 /* We've got new data to write: */
1840 err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
1843 case errSSLWouldBlock:
1844 /* Data was buffered but not sent, we have to tell the caller
1845 to try sending again, and remember how much was buffered */
1846 connssl->ssl_write_buffered_length = len;
1847 *curlcode = CURLE_AGAIN;
1850 failf(conn->data, "SSLWrite() returned error %d", err);
1851 *curlcode = CURLE_SEND_ERROR;
1856 return (ssize_t)processed;
1859 static ssize_t darwinssl_recv(struct connectdata *conn,
1865 /*struct SessionHandle *data = conn->data;*/
1866 struct ssl_connect_data *connssl = &conn->ssl[num];
1867 size_t processed = 0UL;
1868 OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
1872 case errSSLWouldBlock: /* return how much we read (if anything) */
1874 return (ssize_t)processed;
1875 *curlcode = CURLE_AGAIN;
1879 /* errSSLClosedGraceful - server gracefully shut down the SSL session
1880 errSSLClosedNoNotify - server hung up on us instead of sending a
1881 closure alert notice, read() is returning 0
1882 Either way, inform the caller that the server disconnected. */
1883 case errSSLClosedGraceful:
1884 case errSSLClosedNoNotify:
1885 *curlcode = CURLE_OK;
1890 failf(conn->data, "SSLRead() return error %d", err);
1891 *curlcode = CURLE_RECV_ERROR;
1896 return (ssize_t)processed;
1899 #endif /* USE_DARWINSSL */