1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012 - 2015, 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 vtls.c should ever call or use these functions.
29 #include "curl_setup.h"
31 #include "urldata.h" /* for the SessionHandle definition */
32 #include "curl_base64.h"
41 #include <Security/Security.h>
42 #include <Security/SecureTransport.h>
43 #include <CoreFoundation/CoreFoundation.h>
44 #include <CommonCrypto/CommonDigest.h>
46 /* The Security framework has changed greatly between iOS and different OS X
47 versions, and we will try to support as many of them as we can (back to
48 Leopard and iOS 5) by using macros and weak-linking.
50 IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
51 you must build this project against the 10.8 SDK or later. */
52 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
54 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
55 #error "The darwinssl back-end requires Leopard or later."
56 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
58 #define CURL_BUILD_IOS 0
59 #define CURL_BUILD_IOS_7 0
60 #define CURL_BUILD_MAC 1
61 /* This is the maximum API level we are allowed to use when building: */
62 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
63 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
64 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
65 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
66 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
67 /* These macros mean "the following code is present to allow runtime backward
68 compatibility with at least this cat or earlier":
69 (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
70 environmental variable.) */
71 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
72 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
73 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
74 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
75 #define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
77 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
78 #define CURL_BUILD_IOS 1
79 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
80 #define CURL_BUILD_MAC 0
81 #define CURL_BUILD_MAC_10_5 0
82 #define CURL_BUILD_MAC_10_6 0
83 #define CURL_BUILD_MAC_10_7 0
84 #define CURL_BUILD_MAC_10_8 0
85 #define CURL_SUPPORT_MAC_10_5 0
86 #define CURL_SUPPORT_MAC_10_6 0
87 #define CURL_SUPPORT_MAC_10_7 0
88 #define CURL_SUPPORT_MAC_10_8 0
89 #define CURL_SUPPORT_MAC_10_9 0
92 #error "The darwinssl back-end requires iOS or OS X."
93 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
96 #include <sys/sysctl.h>
97 #endif /* CURL_BUILD_MAC */
101 #include "inet_pton.h"
105 #include "curl_darwinssl.h"
107 #define _MPRINTF_REPLACE /* use our functions only */
108 #include <curl/mprintf.h>
110 #include "curl_memory.h"
111 /* The last #include file should be: */
112 #include "memdebug.h"
114 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
118 /* The following two functions were ripped from Apple sample code,
119 * with some modifications: */
120 static OSStatus SocketRead(SSLConnectionRef connection,
121 void *data, /* owned by
124 size_t *dataLength) /* IN/OUT */
126 size_t bytesToGo = *dataLength;
127 size_t initLen = bytesToGo;
128 UInt8 *currData = (UInt8 *)data;
129 /*int sock = *(int *)connection;*/
130 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
131 int sock = connssl->ssl_sockfd;
132 OSStatus rtn = noErr;
141 rrtn = read(sock, currData, bytesToGo);
143 /* this is guesswork... */
145 if(rrtn == 0) { /* EOF = server hung up */
146 /* the framework will turn this into errSSLClosedNoNotify */
147 rtn = errSSLClosedGraceful;
149 else /* do the switch */
152 /* connection closed */
153 rtn = errSSLClosedGraceful;
156 rtn = errSSLClosedAbort;
159 rtn = errSSLWouldBlock;
160 connssl->ssl_direction = false;
171 bytesToGo -= bytesRead;
172 currData += bytesRead;
175 /* filled buffer with incoming data, done */
179 *dataLength = initLen - bytesToGo;
184 static OSStatus SocketWrite(SSLConnectionRef connection,
186 size_t *dataLength) /* IN/OUT */
188 size_t bytesSent = 0;
189 /*int sock = *(int *)connection;*/
190 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
191 int sock = connssl->ssl_sockfd;
193 size_t dataLen = *dataLength;
194 const UInt8 *dataPtr = (UInt8 *)data;
202 (char*)dataPtr + bytesSent,
203 dataLen - bytesSent);
204 } while((length > 0) &&
205 ( (bytesSent += length) < dataLen) );
209 if(theErr == EAGAIN) {
210 ortn = errSSLWouldBlock;
211 connssl->ssl_direction = true;
220 *dataLength = bytesSent;
224 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
226 /* SSL version 3.0 */
227 case SSL_RSA_WITH_NULL_MD5:
228 return "SSL_RSA_WITH_NULL_MD5";
230 case SSL_RSA_WITH_NULL_SHA:
231 return "SSL_RSA_WITH_NULL_SHA";
233 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
234 return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
236 case SSL_RSA_WITH_RC4_128_MD5:
237 return "SSL_RSA_WITH_RC4_128_MD5";
239 case SSL_RSA_WITH_RC4_128_SHA:
240 return "SSL_RSA_WITH_RC4_128_SHA";
242 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
243 return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
245 case SSL_RSA_WITH_IDEA_CBC_SHA:
246 return "SSL_RSA_WITH_IDEA_CBC_SHA";
248 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
249 return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
251 case SSL_RSA_WITH_DES_CBC_SHA:
252 return "SSL_RSA_WITH_DES_CBC_SHA";
254 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
255 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
257 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
258 return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
260 case SSL_DH_DSS_WITH_DES_CBC_SHA:
261 return "SSL_DH_DSS_WITH_DES_CBC_SHA";
263 case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
264 return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
266 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
267 return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
269 case SSL_DH_RSA_WITH_DES_CBC_SHA:
270 return "SSL_DH_RSA_WITH_DES_CBC_SHA";
272 case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
273 return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
275 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
276 return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
278 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
279 return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
281 case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
282 return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
284 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
285 return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
287 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
288 return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
290 case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
291 return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
293 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
294 return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
296 case SSL_DH_anon_WITH_RC4_128_MD5:
297 return "SSL_DH_anon_WITH_RC4_128_MD5";
299 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
300 return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
302 case SSL_DH_anon_WITH_DES_CBC_SHA:
303 return "SSL_DH_anon_WITH_DES_CBC_SHA";
305 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
306 return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
308 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
309 return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
311 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
312 return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
314 /* TLS 1.0 with AES (RFC 3268)
315 (Apparently these are used in SSLv3 implementations as well.) */
316 case TLS_RSA_WITH_AES_128_CBC_SHA:
317 return "TLS_RSA_WITH_AES_128_CBC_SHA";
319 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
320 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
322 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
323 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
325 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
326 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
328 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
329 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
331 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
332 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
334 case TLS_RSA_WITH_AES_256_CBC_SHA:
335 return "TLS_RSA_WITH_AES_256_CBC_SHA";
337 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
338 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
340 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
341 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
343 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
344 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
346 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
347 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
349 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
350 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
352 /* SSL version 2.0 */
353 case SSL_RSA_WITH_RC2_CBC_MD5:
354 return "SSL_RSA_WITH_RC2_CBC_MD5";
356 case SSL_RSA_WITH_IDEA_CBC_MD5:
357 return "SSL_RSA_WITH_IDEA_CBC_MD5";
359 case SSL_RSA_WITH_DES_CBC_MD5:
360 return "SSL_RSA_WITH_DES_CBC_MD5";
362 case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
363 return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
366 return "SSL_NULL_WITH_NULL_NULL";
369 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
371 /* TLS 1.0 with AES (RFC 3268) */
372 case TLS_RSA_WITH_AES_128_CBC_SHA:
373 return "TLS_RSA_WITH_AES_128_CBC_SHA";
375 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
376 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
378 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
379 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
381 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
382 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
384 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
385 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
387 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
388 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
390 case TLS_RSA_WITH_AES_256_CBC_SHA:
391 return "TLS_RSA_WITH_AES_256_CBC_SHA";
393 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
394 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
396 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
397 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
399 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
400 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
402 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
403 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
405 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
406 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
408 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
409 /* TLS 1.0 with ECDSA (RFC 4492) */
410 case TLS_ECDH_ECDSA_WITH_NULL_SHA:
411 return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
413 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
414 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
416 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
417 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
419 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
420 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
422 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
423 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
425 case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
426 return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
428 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
429 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
431 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
432 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
434 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
435 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
437 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
438 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
440 case TLS_ECDH_RSA_WITH_NULL_SHA:
441 return "TLS_ECDH_RSA_WITH_NULL_SHA";
443 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
444 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
446 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
447 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
449 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
450 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
452 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
453 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
455 case TLS_ECDHE_RSA_WITH_NULL_SHA:
456 return "TLS_ECDHE_RSA_WITH_NULL_SHA";
458 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
459 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
461 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
462 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
464 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
465 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
467 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
468 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
470 case TLS_ECDH_anon_WITH_NULL_SHA:
471 return "TLS_ECDH_anon_WITH_NULL_SHA";
473 case TLS_ECDH_anon_WITH_RC4_128_SHA:
474 return "TLS_ECDH_anon_WITH_RC4_128_SHA";
476 case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
477 return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
479 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
480 return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
482 case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
483 return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
485 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
486 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
487 /* TLS 1.2 (RFC 5246) */
488 case TLS_RSA_WITH_NULL_MD5:
489 return "TLS_RSA_WITH_NULL_MD5";
491 case TLS_RSA_WITH_NULL_SHA:
492 return "TLS_RSA_WITH_NULL_SHA";
494 case TLS_RSA_WITH_RC4_128_MD5:
495 return "TLS_RSA_WITH_RC4_128_MD5";
497 case TLS_RSA_WITH_RC4_128_SHA:
498 return "TLS_RSA_WITH_RC4_128_SHA";
500 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
501 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
503 case TLS_RSA_WITH_NULL_SHA256:
504 return "TLS_RSA_WITH_NULL_SHA256";
506 case TLS_RSA_WITH_AES_128_CBC_SHA256:
507 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
509 case TLS_RSA_WITH_AES_256_CBC_SHA256:
510 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
512 case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
513 return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
515 case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
516 return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
518 case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
519 return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
521 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
522 return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
524 case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
525 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
527 case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
528 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
530 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
531 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
533 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
534 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
536 case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
537 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
539 case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
540 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
542 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
543 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
545 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
546 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
548 case TLS_DH_anon_WITH_RC4_128_MD5:
549 return "TLS_DH_anon_WITH_RC4_128_MD5";
551 case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
552 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
554 case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
555 return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
557 case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
558 return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
560 /* TLS 1.2 with AES GCM (RFC 5288) */
561 case TLS_RSA_WITH_AES_128_GCM_SHA256:
562 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
564 case TLS_RSA_WITH_AES_256_GCM_SHA384:
565 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
567 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
568 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
570 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
571 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
573 case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
574 return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
576 case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
577 return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
579 case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
580 return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
582 case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
583 return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
585 case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
586 return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
588 case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
589 return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
591 case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
592 return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
594 case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
595 return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
597 /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
598 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
599 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
601 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
602 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
604 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
605 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
607 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
608 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
610 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
611 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
613 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
614 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
616 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
617 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
619 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
620 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
622 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
623 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
625 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
626 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
628 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
629 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
631 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
632 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
634 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
635 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
637 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
638 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
640 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
641 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
643 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
644 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
646 case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
647 return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
650 case SSL_RSA_WITH_NULL_MD5:
651 return "TLS_RSA_WITH_NULL_MD5";
653 case SSL_RSA_WITH_NULL_SHA:
654 return "TLS_RSA_WITH_NULL_SHA";
656 case SSL_RSA_WITH_RC4_128_MD5:
657 return "TLS_RSA_WITH_RC4_128_MD5";
659 case SSL_RSA_WITH_RC4_128_SHA:
660 return "TLS_RSA_WITH_RC4_128_SHA";
662 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
663 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
665 case SSL_DH_anon_WITH_RC4_128_MD5:
666 return "TLS_DH_anon_WITH_RC4_128_MD5";
668 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
669 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
671 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
672 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
673 /* TLS PSK (RFC 4279): */
674 case TLS_PSK_WITH_RC4_128_SHA:
675 return "TLS_PSK_WITH_RC4_128_SHA";
677 case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
678 return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
680 case TLS_PSK_WITH_AES_128_CBC_SHA:
681 return "TLS_PSK_WITH_AES_128_CBC_SHA";
683 case TLS_PSK_WITH_AES_256_CBC_SHA:
684 return "TLS_PSK_WITH_AES_256_CBC_SHA";
686 case TLS_DHE_PSK_WITH_RC4_128_SHA:
687 return "TLS_DHE_PSK_WITH_RC4_128_SHA";
689 case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
690 return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
692 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
693 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
695 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
696 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
698 case TLS_RSA_PSK_WITH_RC4_128_SHA:
699 return "TLS_RSA_PSK_WITH_RC4_128_SHA";
701 case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
702 return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
704 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
705 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
707 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
708 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
710 /* More TLS PSK (RFC 4785): */
711 case TLS_PSK_WITH_NULL_SHA:
712 return "TLS_PSK_WITH_NULL_SHA";
714 case TLS_DHE_PSK_WITH_NULL_SHA:
715 return "TLS_DHE_PSK_WITH_NULL_SHA";
717 case TLS_RSA_PSK_WITH_NULL_SHA:
718 return "TLS_RSA_PSK_WITH_NULL_SHA";
720 /* Even more TLS PSK (RFC 5487): */
721 case TLS_PSK_WITH_AES_128_GCM_SHA256:
722 return "TLS_PSK_WITH_AES_128_GCM_SHA256";
724 case TLS_PSK_WITH_AES_256_GCM_SHA384:
725 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
727 case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
728 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
730 case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
731 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
733 case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
734 return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
736 case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
737 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
739 case TLS_PSK_WITH_AES_128_CBC_SHA256:
740 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
742 case TLS_PSK_WITH_AES_256_CBC_SHA384:
743 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
745 case TLS_PSK_WITH_NULL_SHA256:
746 return "TLS_PSK_WITH_NULL_SHA256";
748 case TLS_PSK_WITH_NULL_SHA384:
749 return "TLS_PSK_WITH_NULL_SHA384";
751 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
752 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
754 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
755 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
757 case TLS_DHE_PSK_WITH_NULL_SHA256:
758 return "TLS_DHE_PSK_WITH_NULL_SHA256";
760 case TLS_DHE_PSK_WITH_NULL_SHA384:
761 return "TLS_RSA_PSK_WITH_NULL_SHA384";
763 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
764 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
766 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
767 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
769 case TLS_RSA_PSK_WITH_NULL_SHA256:
770 return "TLS_RSA_PSK_WITH_NULL_SHA256";
772 case TLS_RSA_PSK_WITH_NULL_SHA384:
773 return "TLS_RSA_PSK_WITH_NULL_SHA384";
775 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
777 return "TLS_NULL_WITH_NULL_NULL";
781 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
785 size_t os_version_len;
786 char *os_version_major, *os_version_minor/*, *os_version_point*/;
789 /* Get the Darwin kernel version from the kernel using sysctl(): */
791 mib[1] = KERN_OSRELEASE;
792 if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
794 os_version = malloc(os_version_len*sizeof(char));
797 if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
802 /* Parse the version: */
803 os_version_major = strtok_r(os_version, ".", &tok_buf);
804 os_version_minor = strtok_r(NULL, ".", &tok_buf);
805 /*os_version_point = strtok_r(NULL, ".", &tok_buf);*/
806 *major = atoi(os_version_major);
807 *minor = atoi(os_version_minor);
810 #endif /* CURL_BUILD_MAC */
812 /* Apple provides a myriad of ways of getting information about a certificate
813 into a string. Some aren't available under iOS or newer cats. So here's
814 a unified function for getting a string describing the certificate that
815 ought to work in all cats starting with Leopard. */
816 CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
818 CFStringRef server_cert_summary = CFSTR("(null)");
821 /* iOS: There's only one way to do this. */
822 server_cert_summary = SecCertificateCopySubjectSummary(cert);
824 #if CURL_BUILD_MAC_10_7
825 /* Lion & later: Get the long description if we can. */
826 if(SecCertificateCopyLongDescription != NULL)
827 server_cert_summary =
828 SecCertificateCopyLongDescription(NULL, cert, NULL);
830 #endif /* CURL_BUILD_MAC_10_7 */
831 #if CURL_BUILD_MAC_10_6
832 /* Snow Leopard: Get the certificate summary. */
833 if(SecCertificateCopySubjectSummary != NULL)
834 server_cert_summary = SecCertificateCopySubjectSummary(cert);
836 #endif /* CURL_BUILD_MAC_10_6 */
837 /* Leopard is as far back as we go... */
838 (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
839 #endif /* CURL_BUILD_IOS */
840 return server_cert_summary;
843 #if CURL_SUPPORT_MAC_10_6
844 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
845 deprecation warnings, so let's not compile this unless it's necessary: */
846 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
847 SecIdentityRef *out_c_a_k)
849 OSStatus status = errSecItemNotFound;
850 SecKeychainAttributeList attr_list;
851 SecKeychainAttribute attr;
852 SecKeychainSearchRef search = NULL;
853 SecCertificateRef cert = NULL;
855 /* Set up the attribute list: */
856 attr_list.count = 1L;
857 attr_list.attr = &attr;
859 /* Set up our lone search criterion: */
860 attr.tag = kSecLabelItemAttr;
862 attr.length = (UInt32)strlen(label);
864 /* Start searching: */
865 status = SecKeychainSearchCreateFromAttributes(NULL,
866 kSecCertificateItemClass,
869 if(status == noErr) {
870 status = SecKeychainSearchCopyNext(search,
871 (SecKeychainItemRef *)&cert);
872 if(status == noErr && cert) {
873 /* If we found a certificate, does it have a private key? */
874 status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
883 #endif /* CURL_SUPPORT_MAC_10_6 */
885 static OSStatus CopyIdentityWithLabel(char *label,
886 SecIdentityRef *out_cert_and_key)
888 OSStatus status = errSecItemNotFound;
890 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
891 /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
892 kSecClassIdentity was introduced in Lion. If both exist, let's use them
893 to find the certificate. */
894 if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
897 CFDictionaryRef query_dict;
898 CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
899 kCFStringEncodingUTF8);
901 /* Set up our search criteria and expected results: */
902 values[0] = kSecClassIdentity; /* we want a certificate and a key */
904 values[1] = kCFBooleanTrue; /* we want a reference */
905 keys[1] = kSecReturnRef;
906 values[2] = kSecMatchLimitOne; /* one is enough, thanks */
907 keys[2] = kSecMatchLimit;
908 /* identity searches need a SecPolicyRef in order to work */
909 values[3] = SecPolicyCreateSSL(false, label_cf);
910 keys[3] = kSecMatchPolicy;
911 query_dict = CFDictionaryCreate(NULL, (const void **)keys,
912 (const void **)values, 4L,
913 &kCFCopyStringDictionaryKeyCallBacks,
914 &kCFTypeDictionaryValueCallBacks);
915 CFRelease(values[3]);
918 /* Do we have a match? */
919 status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
920 CFRelease(query_dict);
923 #if CURL_SUPPORT_MAC_10_6
924 /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
925 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
926 #endif /* CURL_SUPPORT_MAC_10_7 */
928 #elif CURL_SUPPORT_MAC_10_6
929 /* For developers building on older cats, we have no choice but to fall back
930 to SecKeychainSearch. */
931 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
932 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
936 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
937 const char *cPassword,
938 SecIdentityRef *out_cert_and_key)
940 OSStatus status = errSecItemNotFound;
941 CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
942 (const UInt8 *)cPath, strlen(cPath), false);
943 CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
944 cPassword, kCFStringEncodingUTF8) : NULL;
945 CFDataRef pkcs_data = NULL;
947 /* We can import P12 files on iOS or OS X 10.7 or later: */
948 /* These constants are documented as having first appeared in 10.6 but they
949 raise linker errors when used on that cat for some reason. */
950 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
951 if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
952 NULL, NULL, &status)) {
953 const void *cKeys[] = {kSecImportExportPassphrase};
954 const void *cValues[] = {password};
955 CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
956 password ? 1L : 0L, NULL, NULL);
957 CFArrayRef items = NULL;
960 status = SecPKCS12Import(pkcs_data, options, &items);
961 if(status == noErr && items && CFArrayGetCount(items)) {
962 CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
963 const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
964 kSecImportItemIdentity);
966 /* Retain the identity; we don't care about any other data... */
967 CFRetain(temp_identity);
968 *out_cert_and_key = (SecIdentityRef)temp_identity;
974 CFRelease(pkcs_data);
976 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
983 /* This code was borrowed from nss.c, with some modifications:
984 * Determine whether the nickname passed in is a filename that needs to
985 * be loaded as a PEM or a regular NSS nickname.
987 * returns 1 for a file
988 * returns 0 for not a file
990 CF_INLINE bool is_file(const char *filename)
997 if(stat(filename, &st) == 0)
998 return S_ISREG(st.st_mode);
1002 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
1005 struct SessionHandle *data = conn->data;
1006 curl_socket_t sockfd = conn->sock[sockindex];
1007 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1009 struct in6_addr addr;
1011 struct in_addr addr;
1012 #endif /* ENABLE_IPV6 */
1013 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1014 SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1015 char *ssl_sessionid;
1016 size_t ssl_sessionid_len;
1017 OSStatus err = noErr;
1019 int darwinver_maj = 0, darwinver_min = 0;
1021 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1022 #endif /* CURL_BUILD_MAC */
1024 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1025 if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
1026 if(connssl->ssl_ctx)
1027 CFRelease(connssl->ssl_ctx);
1028 connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1029 if(!connssl->ssl_ctx) {
1030 failf(data, "SSL: couldn't create a context!");
1031 return CURLE_OUT_OF_MEMORY;
1035 /* The old ST API does not exist under iOS, so don't compile it: */
1036 #if CURL_SUPPORT_MAC_10_8
1037 if(connssl->ssl_ctx)
1038 (void)SSLDisposeContext(connssl->ssl_ctx);
1039 err = SSLNewContext(false, &(connssl->ssl_ctx));
1041 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1042 return CURLE_OUT_OF_MEMORY;
1044 #endif /* CURL_SUPPORT_MAC_10_8 */
1047 if(connssl->ssl_ctx)
1048 (void)SSLDisposeContext(connssl->ssl_ctx);
1049 err = SSLNewContext(false, &(connssl->ssl_ctx));
1051 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1052 return CURLE_OUT_OF_MEMORY;
1054 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1055 connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1057 /* check to see if we've been told to use an explicit SSL/TLS version */
1058 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1059 if(SSLSetProtocolVersionMax != NULL) {
1060 switch(data->set.ssl.version) {
1062 case CURL_SSLVERSION_DEFAULT:
1063 case CURL_SSLVERSION_TLSv1:
1064 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1065 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1067 case CURL_SSLVERSION_TLSv1_0:
1068 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1069 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
1071 case CURL_SSLVERSION_TLSv1_1:
1072 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
1073 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
1075 case CURL_SSLVERSION_TLSv1_2:
1076 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
1077 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1079 case CURL_SSLVERSION_SSLv3:
1080 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1082 failf(data, "Your version of the OS does not support SSLv3");
1083 return CURLE_SSL_CONNECT_ERROR;
1085 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
1087 case CURL_SSLVERSION_SSLv2:
1088 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
1090 failf(data, "Your version of the OS does not support SSLv2");
1091 return CURLE_SSL_CONNECT_ERROR;
1093 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
1097 #if CURL_SUPPORT_MAC_10_8
1098 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1101 switch (data->set.ssl.version) {
1103 case CURL_SSLVERSION_DEFAULT:
1104 case CURL_SSLVERSION_TLSv1:
1105 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1108 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1111 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1115 case CURL_SSLVERSION_TLSv1_0:
1116 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1120 case CURL_SSLVERSION_TLSv1_1:
1121 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1125 case CURL_SSLVERSION_TLSv1_2:
1126 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1130 case CURL_SSLVERSION_SSLv3:
1131 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1135 failf(data, "Your version of the OS does not support SSLv3");
1136 return CURLE_SSL_CONNECT_ERROR;
1139 case CURL_SSLVERSION_SSLv2:
1140 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1144 failf(data, "Your version of the OS does not support SSLv2");
1145 return CURLE_SSL_CONNECT_ERROR;
1149 #endif /* CURL_SUPPORT_MAC_10_8 */
1152 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
1153 switch(data->set.ssl.version) {
1155 case CURL_SSLVERSION_DEFAULT:
1156 case CURL_SSLVERSION_TLSv1:
1157 case CURL_SSLVERSION_TLSv1_0:
1158 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1162 case CURL_SSLVERSION_TLSv1_1:
1163 failf(data, "Your version of the OS does not support TLSv1.1");
1164 return CURLE_SSL_CONNECT_ERROR;
1165 case CURL_SSLVERSION_TLSv1_2:
1166 failf(data, "Your version of the OS does not support TLSv1.2");
1167 return CURLE_SSL_CONNECT_ERROR;
1168 case CURL_SSLVERSION_SSLv2:
1169 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1173 failf(data, "Your version of the OS does not support SSLv2");
1174 return CURLE_SSL_CONNECT_ERROR;
1177 case CURL_SSLVERSION_SSLv3:
1178 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1182 failf(data, "Your version of the OS does not support SSLv3");
1183 return CURLE_SSL_CONNECT_ERROR;
1187 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1189 if(data->set.str[STRING_KEY]) {
1190 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1191 "Transport. The private key must be in the Keychain.\n");
1194 if(data->set.str[STRING_CERT]) {
1195 SecIdentityRef cert_and_key = NULL;
1196 bool is_cert_file = is_file(data->set.str[STRING_CERT]);
1198 /* User wants to authenticate with a client cert. Look for it:
1199 If we detect that this is a file on disk, then let's load it.
1200 Otherwise, assume that the user wants to use an identity loaded
1201 from the Keychain. */
1203 if(!data->set.str[STRING_CERT_TYPE])
1204 infof(data, "WARNING: SSL: Certificate type not set, assuming "
1205 "PKCS#12 format.\n");
1206 else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
1207 strlen(data->set.str[STRING_CERT_TYPE])) != 0)
1208 infof(data, "WARNING: SSL: The Security framework only supports "
1209 "loading identities that are in PKCS#12 format.\n");
1211 err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
1212 data->set.str[STRING_KEY_PASSWD], &cert_and_key);
1215 err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
1218 SecCertificateRef cert = NULL;
1219 CFTypeRef certs_c[1];
1222 /* If we found one, print it out: */
1223 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1225 CFStringRef cert_summary = CopyCertSubject(cert);
1226 char cert_summary_c[128];
1229 memset(cert_summary_c, 0, 128);
1230 if(CFStringGetCString(cert_summary,
1233 kCFStringEncodingUTF8)) {
1234 infof(data, "Client certificate: %s\n", cert_summary_c);
1236 CFRelease(cert_summary);
1240 certs_c[0] = cert_and_key;
1241 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1242 &kCFTypeArrayCallBacks);
1243 err = SSLSetCertificate(connssl->ssl_ctx, certs);
1247 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1248 return CURLE_SSL_CERTPROBLEM;
1250 CFRelease(cert_and_key);
1254 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1255 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1256 "and its private key.", data->set.str[STRING_CERT]);
1258 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1259 failf(data, "SSL: Couldn't make sense of the data in the "
1260 "certificate \"%s\" and its private key.",
1261 data->set.str[STRING_CERT]);
1263 case -25260: /* errSecPassphraseRequired */
1264 failf(data, "SSL The certificate \"%s\" requires a password.",
1265 data->set.str[STRING_CERT]);
1267 case errSecItemNotFound:
1268 failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1269 "key in the Keychain.", data->set.str[STRING_CERT]);
1272 failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1273 "key: OSStatus %d", data->set.str[STRING_CERT], err);
1276 return CURLE_SSL_CERTPROBLEM;
1280 /* SSL always tries to verify the peer, this only says whether it should
1281 * fail to connect if the verification fails, or if it should continue
1282 * anyway. In the latter case the result of the verification is checked with
1283 * SSL_get_verify_result() below. */
1284 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1285 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1286 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1287 works, it doesn't work as expected under Snow Leopard or Lion.
1288 So we need to call SSLSetEnableCertVerify() on those older cats in order
1289 to disable certificate validation if the user turned that off.
1290 (SecureTransport will always validate the certificate chain by
1292 /* (Note: Darwin 12.x.x is Mountain Lion.) */
1294 if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
1296 if(SSLSetSessionOption != NULL) {
1297 #endif /* CURL_BUILD_MAC */
1298 bool break_on_auth = !data->set.ssl.verifypeer ||
1299 data->set.str[STRING_SSL_CAFILE];
1300 err = SSLSetSessionOption(connssl->ssl_ctx,
1301 kSSLSessionOptionBreakOnServerAuth,
1304 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1305 return CURLE_SSL_CONNECT_ERROR;
1309 #if CURL_SUPPORT_MAC_10_8
1310 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1311 data->set.ssl.verifypeer?true:false);
1313 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1314 return CURLE_SSL_CONNECT_ERROR;
1316 #endif /* CURL_SUPPORT_MAC_10_8 */
1319 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1320 data->set.ssl.verifypeer?true:false);
1322 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1323 return CURLE_SSL_CONNECT_ERROR;
1325 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1327 if(data->set.str[STRING_SSL_CAFILE]) {
1328 bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
1331 failf(data, "SSL: can't load CA certificate file %s",
1332 data->set.str[STRING_SSL_CAFILE]);
1333 return CURLE_SSL_CACERT_BADFILE;
1335 if(!data->set.ssl.verifypeer) {
1336 failf(data, "SSL: CA certificate set, but certificate verification "
1338 return CURLE_SSL_CONNECT_ERROR;
1342 /* Configure hostname check. SNI is used if available.
1343 * Both hostname check and SNI require SSLSetPeerDomainName().
1344 * Also: the verifyhost setting influences SNI usage */
1345 if(data->set.ssl.verifyhost) {
1346 err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1347 strlen(conn->host.name));
1350 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1354 if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
1356 || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
1359 infof(data, "WARNING: using IP address, SNI is being disabled by "
1364 /* Disable cipher suites that ST supports but are not safe. These ciphers
1365 are unlikely to be used in any case since ST gives other ciphers a much
1366 higher priority, but it's probably better that we not connect at all than
1367 to give the user a false sense of security if the server only supports
1368 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1369 (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1370 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1371 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1372 if(all_ciphers && allowed_ciphers &&
1373 SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1374 &all_ciphers_count) == noErr) {
1375 for(i = 0UL ; i < all_ciphers_count ; i++) {
1377 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1378 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1379 Work around the problem here by disabling those ciphers if we are
1380 running in an affected version of OS X. */
1381 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1382 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1385 #endif /* CURL_BUILD_MAC */
1386 switch(all_ciphers[i]) {
1387 /* Disable NULL ciphersuites: */
1388 case SSL_NULL_WITH_NULL_NULL:
1389 case SSL_RSA_WITH_NULL_MD5:
1390 case SSL_RSA_WITH_NULL_SHA:
1391 case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1392 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1393 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1394 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1395 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1396 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1397 case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1398 case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1399 case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1400 case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1401 case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1402 case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1403 case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1404 case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1405 case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1406 /* Disable anonymous ciphersuites: */
1407 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1408 case SSL_DH_anon_WITH_RC4_128_MD5:
1409 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1410 case SSL_DH_anon_WITH_DES_CBC_SHA:
1411 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1412 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1413 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1414 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1415 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1416 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1417 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1418 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1419 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1420 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1421 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1422 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1423 /* Disable weak key ciphersuites: */
1424 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1425 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1426 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1427 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1428 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1429 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1430 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1431 case SSL_RSA_WITH_DES_CBC_SHA:
1432 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1433 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1434 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1435 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1437 case SSL_RSA_WITH_IDEA_CBC_SHA:
1438 case SSL_RSA_WITH_IDEA_CBC_MD5:
1440 default: /* enable everything else */
1441 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1445 err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1446 allowed_ciphers_count);
1448 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1449 return CURLE_SSL_CONNECT_ERROR;
1453 Curl_safefree(all_ciphers);
1454 Curl_safefree(allowed_ciphers);
1455 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1456 return CURLE_OUT_OF_MEMORY;
1458 Curl_safefree(all_ciphers);
1459 Curl_safefree(allowed_ciphers);
1461 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1462 /* We want to enable 1/n-1 when using a CBC cipher unless the user
1463 specifically doesn't want us doing that: */
1464 if(SSLSetSessionOption != NULL)
1465 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1466 !data->set.ssl_enable_beast);
1467 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1469 /* Check if there's a cached ID we can/should use here! */
1470 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1471 &ssl_sessionid_len)) {
1472 /* we got a session id, use it! */
1473 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1475 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1476 return CURLE_SSL_CONNECT_ERROR;
1478 /* Informational message */
1479 infof(data, "SSL re-using session ID\n");
1481 /* If there isn't one, then let's make one up! This has to be done prior
1482 to starting the handshake. */
1486 aprintf("%s:%d:%d:%s:%hu", data->set.str[STRING_SSL_CAFILE],
1487 data->set.ssl.verifypeer, data->set.ssl.verifyhost,
1488 conn->host.name, conn->remote_port);
1489 ssl_sessionid_len = strlen(ssl_sessionid);
1491 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1493 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1494 return CURLE_SSL_CONNECT_ERROR;
1497 result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1499 failf(data, "failed to store ssl session");
1504 err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1506 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1507 return CURLE_SSL_CONNECT_ERROR;
1510 /* pass the raw socket into the SSL layers */
1511 /* We need to store the FD in a constant memory address, because
1512 * SSLSetConnection() will not copy that address. I've found that
1513 * conn->sock[sockindex] may change on its own. */
1514 connssl->ssl_sockfd = sockfd;
1515 err = SSLSetConnection(connssl->ssl_ctx, connssl);
1517 failf(data, "SSL: SSLSetConnection() failed: %d", err);
1518 return CURLE_SSL_CONNECT_ERROR;
1521 connssl->connecting_state = ssl_connect_2;
1525 static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
1527 char *sep_start, *sep_end, *cert_start, *cert_end;
1532 /* Jump through the separators at the beginning of the certificate. */
1533 sep_start = strstr(in, "-----");
1534 if(sep_start == NULL)
1536 cert_start = strstr(sep_start + 1, "-----");
1537 if(cert_start == NULL)
1542 /* Find separator after the end of the certificate. */
1543 cert_end = strstr(cert_start, "-----");
1544 if(cert_end == NULL)
1547 sep_end = strstr(cert_end + 1, "-----");
1552 len = cert_end - cert_start;
1553 b64 = malloc(len + 1);
1557 /* Create base64 string without linefeeds. */
1558 for(i = 0, j = 0; i < len; i++) {
1559 if(cert_start[i] != '\r' && cert_start[i] != '\n')
1560 b64[j++] = cert_start[i];
1564 err = Curl_base64_decode((const char *)b64, out, outlen);
1571 return sep_end - in;
1574 static int read_cert(const char *file, unsigned char **out, size_t *outlen)
1577 ssize_t n, len = 0, cap = 512;
1578 unsigned char buf[cap], *data;
1591 n = read(fd, buf, sizeof(buf));
1602 if(len + n >= cap) {
1604 data = realloc(data, cap);
1611 memcpy(data + len, buf, n);
1622 static int sslerr_to_curlerr(struct SessionHandle *data, int err)
1625 case errSSLXCertChainInvalid:
1626 failf(data, "SSL certificate problem: Invalid certificate chain");
1627 return CURLE_SSL_CACERT;
1628 case errSSLUnknownRootCert:
1629 failf(data, "SSL certificate problem: Untrusted root certificate");
1630 return CURLE_SSL_CACERT;
1631 case errSSLNoRootCert:
1632 failf(data, "SSL certificate problem: No root certificate");
1633 return CURLE_SSL_CACERT;
1634 case errSSLCertExpired:
1635 failf(data, "SSL certificate problem: Certificate chain had an "
1636 "expired certificate");
1637 return CURLE_SSL_CACERT;
1639 failf(data, "SSL certificate problem: Couldn't understand the server "
1640 "certificate format");
1641 return CURLE_SSL_CONNECT_ERROR;
1642 case errSSLHostNameMismatch:
1643 failf(data, "SSL certificate peer hostname mismatch");
1644 return CURLE_PEER_FAILED_VERIFICATION;
1646 failf(data, "SSL unexpected certificate error %d", err);
1647 return CURLE_SSL_CACERT;
1651 static int append_cert_to_array(struct SessionHandle *data,
1652 unsigned char *buf, size_t buflen,
1653 CFMutableArrayRef array)
1655 CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
1657 failf(data, "SSL: failed to allocate array for CA certificate");
1658 return CURLE_OUT_OF_MEMORY;
1661 SecCertificateRef cacert =
1662 SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
1663 CFRelease(certdata);
1665 failf(data, "SSL: failed to create SecCertificate from CA certificate");
1666 return CURLE_SSL_CACERT;
1669 /* Check if cacert is valid. */
1670 CFStringRef subject = CopyCertSubject(cacert);
1672 char subject_cbuf[128];
1673 memset(subject_cbuf, 0, 128);
1674 if(!CFStringGetCString(subject,
1677 kCFStringEncodingUTF8)) {
1679 failf(data, "SSL: invalid CA certificate subject");
1680 return CURLE_SSL_CACERT;
1686 failf(data, "SSL: invalid CA certificate");
1687 return CURLE_SSL_CACERT;
1690 CFArrayAppendValue(array, cacert);
1696 static int verify_cert(const char *cafile, struct SessionHandle *data,
1701 unsigned char *certbuf, *der;
1702 size_t buflen, derlen, offset = 0;
1704 if(read_cert(cafile, &certbuf, &buflen) < 0) {
1705 failf(data, "SSL: failed to read or invalid CA certificate");
1706 return CURLE_SSL_CACERT;
1710 * Certbuf now contains the contents of the certificate file, which can be
1711 * - a single DER certificate,
1712 * - a single PEM certificate or
1713 * - a bunch of PEM certificates (certificate bundle).
1715 * Go through certbuf, and convert any PEM certificate in it into DER
1718 CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
1719 &kCFTypeArrayCallBacks);
1722 failf(data, "SSL: out of memory creating CA certificate array");
1723 return CURLE_OUT_OF_MEMORY;
1726 while(offset < buflen) {
1730 * Check if the certificate is in PEM format, and convert it to DER. If
1731 * this fails, we assume the certificate is in DER format.
1733 res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
1737 failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
1739 return CURLE_SSL_CACERT;
1743 if(res == 0 && offset == 0) {
1744 /* This is not a PEM file, probably a certificate in DER format. */
1745 rc = append_cert_to_array(data, certbuf, buflen, array);
1747 if(rc != CURLE_OK) {
1754 /* No more certificates in the bundle. */
1759 rc = append_cert_to_array(data, der, derlen, array);
1761 if(rc != CURLE_OK) {
1769 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
1771 failf(data, "SSL: error getting certificate chain");
1773 return CURLE_OUT_OF_MEMORY;
1775 else if(ret != noErr) {
1777 return sslerr_to_curlerr(data, ret);
1780 ret = SecTrustSetAnchorCertificates(trust, array);
1783 return sslerr_to_curlerr(data, ret);
1785 ret = SecTrustSetAnchorCertificatesOnly(trust, true);
1788 return sslerr_to_curlerr(data, ret);
1791 SecTrustResultType trust_eval = 0;
1792 ret = SecTrustEvaluate(trust, &trust_eval);
1796 return sslerr_to_curlerr(data, ret);
1799 switch (trust_eval) {
1800 case kSecTrustResultUnspecified:
1801 case kSecTrustResultProceed:
1804 case kSecTrustResultRecoverableTrustFailure:
1805 case kSecTrustResultDeny:
1807 failf(data, "SSL: certificate verification failed (result: %d)",
1809 return CURLE_PEER_FAILED_VERIFICATION;
1814 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1816 struct SessionHandle *data = conn->data;
1817 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1819 SSLCipherSuite cipher;
1820 SSLProtocol protocol = 0;
1822 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1823 || ssl_connect_2_reading == connssl->connecting_state
1824 || ssl_connect_2_writing == connssl->connecting_state);
1826 /* Here goes nothing: */
1827 err = SSLHandshake(connssl->ssl_ctx);
1831 case errSSLWouldBlock: /* they're not done with us yet */
1832 connssl->connecting_state = connssl->ssl_direction ?
1833 ssl_connect_2_writing : ssl_connect_2_reading;
1836 /* The below is errSSLServerAuthCompleted; it's not defined in
1837 Leopard's headers */
1839 if(data->set.str[STRING_SSL_CAFILE]) {
1840 int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
1845 /* the documentation says we need to call SSLHandshake() again */
1846 return darwinssl_connect_step2(conn, sockindex);
1848 /* These are all certificate problems with the server: */
1849 case errSSLXCertChainInvalid:
1850 failf(data, "SSL certificate problem: Invalid certificate chain");
1851 return CURLE_SSL_CACERT;
1852 case errSSLUnknownRootCert:
1853 failf(data, "SSL certificate problem: Untrusted root certificate");
1854 return CURLE_SSL_CACERT;
1855 case errSSLNoRootCert:
1856 failf(data, "SSL certificate problem: No root certificate");
1857 return CURLE_SSL_CACERT;
1858 case errSSLCertExpired:
1859 failf(data, "SSL certificate problem: Certificate chain had an "
1860 "expired certificate");
1861 return CURLE_SSL_CACERT;
1863 failf(data, "SSL certificate problem: Couldn't understand the server "
1864 "certificate format");
1865 return CURLE_SSL_CONNECT_ERROR;
1867 /* These are all certificate problems with the client: */
1868 case errSecAuthFailed:
1869 failf(data, "SSL authentication failed");
1870 return CURLE_SSL_CONNECT_ERROR;
1871 case errSSLPeerHandshakeFail:
1872 failf(data, "SSL peer handshake failed, the server most likely "
1873 "requires a client certificate to connect");
1874 return CURLE_SSL_CONNECT_ERROR;
1875 case errSSLPeerUnknownCA:
1876 failf(data, "SSL server rejected the client certificate due to "
1877 "the certificate being signed by an unknown certificate "
1879 return CURLE_SSL_CONNECT_ERROR;
1881 /* This error is raised if the server's cert didn't match the server's
1883 case errSSLHostNameMismatch:
1884 failf(data, "SSL certificate peer verification failed, the "
1885 "certificate did not match \"%s\"\n", conn->host.dispname);
1886 return CURLE_PEER_FAILED_VERIFICATION;
1888 /* Generic handshake errors: */
1889 case errSSLConnectionRefused:
1890 failf(data, "Server dropped the connection during the SSL handshake");
1891 return CURLE_SSL_CONNECT_ERROR;
1892 case errSSLClosedAbort:
1893 failf(data, "Server aborted the SSL handshake");
1894 return CURLE_SSL_CONNECT_ERROR;
1895 case errSSLNegotiation:
1896 failf(data, "Could not negotiate an SSL cipher suite with the server");
1897 return CURLE_SSL_CONNECT_ERROR;
1898 /* Sometimes paramErr happens with buggy ciphers: */
1899 case paramErr: case errSSLInternal:
1900 failf(data, "Internal SSL engine error encountered during the "
1902 return CURLE_SSL_CONNECT_ERROR;
1903 case errSSLFatalAlert:
1904 failf(data, "Fatal SSL engine error encountered during the SSL "
1906 return CURLE_SSL_CONNECT_ERROR;
1908 failf(data, "Unknown SSL protocol error in connection to %s:%d",
1909 conn->host.name, err);
1910 return CURLE_SSL_CONNECT_ERROR;
1914 /* we have been connected fine, we're not waiting for anything else. */
1915 connssl->connecting_state = ssl_connect_3;
1917 /* Informational message */
1918 (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1919 (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1922 infof(data, "SSL 2.0 connection using %s\n",
1923 SSLCipherNameForNumber(cipher));
1926 infof(data, "SSL 3.0 connection using %s\n",
1927 SSLCipherNameForNumber(cipher));
1930 infof(data, "TLS 1.0 connection using %s\n",
1931 TLSCipherNameForNumber(cipher));
1933 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1934 case kTLSProtocol11:
1935 infof(data, "TLS 1.1 connection using %s\n",
1936 TLSCipherNameForNumber(cipher));
1938 case kTLSProtocol12:
1939 infof(data, "TLS 1.2 connection using %s\n",
1940 TLSCipherNameForNumber(cipher));
1944 infof(data, "Unknown protocol connection\n");
1953 darwinssl_connect_step3(struct connectdata *conn,
1956 struct SessionHandle *data = conn->data;
1957 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1958 CFStringRef server_cert_summary;
1959 char server_cert_summary_c[128];
1960 CFArrayRef server_certs = NULL;
1961 SecCertificateRef server_cert;
1964 SecTrustRef trust = NULL;
1966 /* There is no step 3!
1967 * Well, okay, if verbose mode is on, let's print the details of the
1968 * server certificates. */
1969 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1971 #pragma unused(server_certs)
1972 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1973 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1974 a null trust, so be on guard for that: */
1975 if(err == noErr && trust) {
1976 count = SecTrustGetCertificateCount(trust);
1977 for(i = 0L ; i < count ; i++) {
1978 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1979 server_cert_summary = CopyCertSubject(server_cert);
1980 memset(server_cert_summary_c, 0, 128);
1981 if(CFStringGetCString(server_cert_summary,
1982 server_cert_summary_c,
1984 kCFStringEncodingUTF8)) {
1985 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1987 CFRelease(server_cert_summary);
1992 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
1993 The function SecTrustGetCertificateAtIndex() is officially present
1994 in Lion, but it is unfortunately also present in Snow Leopard as
1995 private API and doesn't work as expected. So we have to look for
1996 a different symbol to make sure this code is only executed under
1998 if(SecTrustEvaluateAsync != NULL) {
1999 #pragma unused(server_certs)
2000 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
2001 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2002 a null trust, so be on guard for that: */
2003 if(err == noErr && trust) {
2004 count = SecTrustGetCertificateCount(trust);
2005 for(i = 0L ; i < count ; i++) {
2006 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2007 server_cert_summary = CopyCertSubject(server_cert);
2008 memset(server_cert_summary_c, 0, 128);
2009 if(CFStringGetCString(server_cert_summary,
2010 server_cert_summary_c,
2012 kCFStringEncodingUTF8)) {
2013 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2015 CFRelease(server_cert_summary);
2021 #if CURL_SUPPORT_MAC_10_8
2022 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
2023 /* Just in case SSLCopyPeerCertificates() returns null too... */
2024 if(err == noErr && server_certs) {
2025 count = CFArrayGetCount(server_certs);
2026 for(i = 0L ; i < count ; i++) {
2027 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
2030 server_cert_summary = CopyCertSubject(server_cert);
2031 memset(server_cert_summary_c, 0, 128);
2032 if(CFStringGetCString(server_cert_summary,
2033 server_cert_summary_c,
2035 kCFStringEncodingUTF8)) {
2036 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2038 CFRelease(server_cert_summary);
2040 CFRelease(server_certs);
2042 #endif /* CURL_SUPPORT_MAC_10_8 */
2044 #endif /* CURL_BUILD_IOS */
2046 #pragma unused(trust)
2047 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
2049 count = CFArrayGetCount(server_certs);
2050 for(i = 0L ; i < count ; i++) {
2051 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
2052 server_cert_summary = CopyCertSubject(server_cert);
2053 memset(server_cert_summary_c, 0, 128);
2054 if(CFStringGetCString(server_cert_summary,
2055 server_cert_summary_c,
2057 kCFStringEncodingUTF8)) {
2058 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2060 CFRelease(server_cert_summary);
2062 CFRelease(server_certs);
2064 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
2066 connssl->connecting_state = ssl_connect_done;
2070 static Curl_recv darwinssl_recv;
2071 static Curl_send darwinssl_send;
2074 darwinssl_connect_common(struct connectdata *conn,
2080 struct SessionHandle *data = conn->data;
2081 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2082 curl_socket_t sockfd = conn->sock[sockindex];
2086 /* check if the connection has already been established */
2087 if(ssl_connection_complete == connssl->state) {
2092 if(ssl_connect_1==connssl->connecting_state) {
2093 /* Find out how much more time we're allowed */
2094 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2096 if(timeout_ms < 0) {
2097 /* no need to continue if time already is up */
2098 failf(data, "SSL connection timeout");
2099 return CURLE_OPERATION_TIMEDOUT;
2102 result = darwinssl_connect_step1(conn, sockindex);
2107 while(ssl_connect_2 == connssl->connecting_state ||
2108 ssl_connect_2_reading == connssl->connecting_state ||
2109 ssl_connect_2_writing == connssl->connecting_state) {
2111 /* check allowed time left */
2112 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2114 if(timeout_ms < 0) {
2115 /* no need to continue if time already is up */
2116 failf(data, "SSL connection timeout");
2117 return CURLE_OPERATION_TIMEDOUT;
2120 /* if ssl is expecting something, check if it's available. */
2121 if(connssl->connecting_state == ssl_connect_2_reading ||
2122 connssl->connecting_state == ssl_connect_2_writing) {
2124 curl_socket_t writefd = ssl_connect_2_writing ==
2125 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2126 curl_socket_t readfd = ssl_connect_2_reading ==
2127 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2129 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
2132 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2133 return CURLE_SSL_CONNECT_ERROR;
2135 else if(0 == what) {
2142 failf(data, "SSL connection timeout");
2143 return CURLE_OPERATION_TIMEDOUT;
2146 /* socket is readable or writable */
2149 /* Run transaction, and return to the caller if it failed or if this
2150 * connection is done nonblocking and this loop would execute again. This
2151 * permits the owner of a multi handle to abort a connection attempt
2152 * before step2 has completed while ensuring that a client using select()
2153 * or epoll() will always have a valid fdset to wait on.
2155 result = darwinssl_connect_step2(conn, sockindex);
2156 if(result || (nonblocking &&
2157 (ssl_connect_2 == connssl->connecting_state ||
2158 ssl_connect_2_reading == connssl->connecting_state ||
2159 ssl_connect_2_writing == connssl->connecting_state)))
2162 } /* repeat step2 until all transactions are done. */
2165 if(ssl_connect_3 == connssl->connecting_state) {
2166 result = darwinssl_connect_step3(conn, sockindex);
2171 if(ssl_connect_done == connssl->connecting_state) {
2172 connssl->state = ssl_connection_complete;
2173 conn->recv[sockindex] = darwinssl_recv;
2174 conn->send[sockindex] = darwinssl_send;
2180 /* Reset our connect state machine */
2181 connssl->connecting_state = ssl_connect_1;
2187 Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
2191 return darwinssl_connect_common(conn, sockindex, TRUE, done);
2195 Curl_darwinssl_connect(struct connectdata *conn,
2201 result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
2211 void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
2213 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2215 if(connssl->ssl_ctx) {
2216 (void)SSLClose(connssl->ssl_ctx);
2217 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2218 if(SSLCreateContext != NULL)
2219 CFRelease(connssl->ssl_ctx);
2220 #if CURL_SUPPORT_MAC_10_8
2222 (void)SSLDisposeContext(connssl->ssl_ctx);
2223 #endif /* CURL_SUPPORT_MAC_10_8 */
2225 (void)SSLDisposeContext(connssl->ssl_ctx);
2226 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2227 connssl->ssl_ctx = NULL;
2229 connssl->ssl_sockfd = 0;
2232 void Curl_darwinssl_close_all(struct SessionHandle *data)
2234 /* SecureTransport doesn't separate sessions from contexts, so... */
2238 int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
2240 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2241 struct SessionHandle *data = conn->data;
2247 if(!connssl->ssl_ctx)
2250 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
2253 Curl_darwinssl_close(conn, sockindex);
2257 what = Curl_socket_ready(conn->sock[sockindex],
2258 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
2262 /* anything that gets here is fatally bad */
2263 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2268 if(!what) { /* timeout */
2269 failf(data, "SSL shutdown timeout");
2273 /* Something to read, let's do it and hope that it is the close
2274 notify alert from the server. No way to SSL_Read now, so use read(). */
2276 nread = read(conn->sock[sockindex], buf, sizeof(buf));
2279 failf(data, "read: %s", strerror(errno));
2286 what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
2292 void Curl_darwinssl_session_free(void *ptr)
2294 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
2295 cached session ID inside the Security framework. There is a private
2296 function that does this, but I don't want to have to explain to you why I
2297 got your application rejected from the App Store due to the use of a
2298 private API, so the best we can do is free up our own char array that we
2299 created way back in darwinssl_connect_step1... */
2303 size_t Curl_darwinssl_version(char *buffer, size_t size)
2305 return snprintf(buffer, size, "SecureTransport");
2309 * This function uses SSLGetSessionState to determine connection status.
2312 * 1 means the connection is still in place
2313 * 0 means the connection has been closed
2314 * -1 means the connection status is unknown
2316 int Curl_darwinssl_check_cxn(struct connectdata *conn)
2318 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2320 SSLSessionState state;
2322 if(connssl->ssl_ctx) {
2323 err = SSLGetSessionState(connssl->ssl_ctx, &state);
2325 return state == kSSLConnected || state == kSSLHandshake;
2331 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2334 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2338 if(connssl->ssl_ctx) { /* SSL is in use */
2339 err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
2341 return buffer > 0UL;
2348 int Curl_darwinssl_random(unsigned char *entropy,
2351 /* arc4random_buf() isn't available on cats older than Lion, so let's
2352 do this manually for the benefit of the older cats. */
2354 u_int32_t random_number = 0;
2356 for(i = 0 ; i < length ; i++) {
2357 if(i % sizeof(u_int32_t) == 0)
2358 random_number = arc4random();
2359 entropy[i] = random_number & 0xFF;
2360 random_number >>= 8;
2362 i = random_number = 0;
2366 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2368 unsigned char *md5sum, /* output */
2372 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2375 static ssize_t darwinssl_send(struct connectdata *conn,
2381 /*struct SessionHandle *data = conn->data;*/
2382 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2383 size_t processed = 0UL;
2386 /* The SSLWrite() function works a little differently than expected. The
2387 fourth argument (processed) is currently documented in Apple's
2388 documentation as: "On return, the length, in bytes, of the data actually
2391 Now, one could interpret that as "written to the socket," but actually,
2392 it returns the amount of data that was written to a buffer internal to
2393 the SSLContextRef instead. So it's possible for SSLWrite() to return
2394 errSSLWouldBlock and a number of bytes "written" because those bytes were
2395 encrypted and written to a buffer, not to the socket.
2397 So if this happens, then we need to keep calling SSLWrite() over and
2398 over again with no new data until it quits returning errSSLWouldBlock. */
2400 /* Do we have buffered data to write from the last time we were called? */
2401 if(connssl->ssl_write_buffered_length) {
2402 /* Write the buffered data: */
2403 err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
2406 /* processed is always going to be 0 because we didn't write to
2407 the buffer, so return how much was written to the socket */
2408 processed = connssl->ssl_write_buffered_length;
2409 connssl->ssl_write_buffered_length = 0UL;
2411 case errSSLWouldBlock: /* argh, try again */
2412 *curlcode = CURLE_AGAIN;
2415 failf(conn->data, "SSLWrite() returned error %d", err);
2416 *curlcode = CURLE_SEND_ERROR;
2421 /* We've got new data to write: */
2422 err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
2425 case errSSLWouldBlock:
2426 /* Data was buffered but not sent, we have to tell the caller
2427 to try sending again, and remember how much was buffered */
2428 connssl->ssl_write_buffered_length = len;
2429 *curlcode = CURLE_AGAIN;
2432 failf(conn->data, "SSLWrite() returned error %d", err);
2433 *curlcode = CURLE_SEND_ERROR;
2438 return (ssize_t)processed;
2441 static ssize_t darwinssl_recv(struct connectdata *conn,
2447 /*struct SessionHandle *data = conn->data;*/
2448 struct ssl_connect_data *connssl = &conn->ssl[num];
2449 size_t processed = 0UL;
2450 OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
2454 case errSSLWouldBlock: /* return how much we read (if anything) */
2456 return (ssize_t)processed;
2457 *curlcode = CURLE_AGAIN;
2461 /* errSSLClosedGraceful - server gracefully shut down the SSL session
2462 errSSLClosedNoNotify - server hung up on us instead of sending a
2463 closure alert notice, read() is returning 0
2464 Either way, inform the caller that the server disconnected. */
2465 case errSSLClosedGraceful:
2466 case errSSLClosedNoNotify:
2467 *curlcode = CURLE_OK;
2472 failf(conn->data, "SSLRead() return error %d", err);
2473 *curlcode = CURLE_RECV_ERROR;
2478 return (ssize_t)processed;
2481 #endif /* USE_DARWINSSL */