1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012 - 2014, 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"
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_IOS_7 0
56 #define CURL_BUILD_MAC 1
57 /* This is the maximum API level we are allowed to use when building: */
58 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
59 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
60 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
61 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
62 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
63 /* These macros mean "the following code is present to allow runtime backward
64 compatibility with at least this cat or earlier":
65 (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
66 environmental variable.) */
67 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
68 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
69 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
70 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
71 #define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
73 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
74 #define CURL_BUILD_IOS 1
75 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
76 #define CURL_BUILD_MAC 0
77 #define CURL_BUILD_MAC_10_5 0
78 #define CURL_BUILD_MAC_10_6 0
79 #define CURL_BUILD_MAC_10_7 0
80 #define CURL_BUILD_MAC_10_8 0
81 #define CURL_SUPPORT_MAC_10_5 0
82 #define CURL_SUPPORT_MAC_10_6 0
83 #define CURL_SUPPORT_MAC_10_7 0
84 #define CURL_SUPPORT_MAC_10_8 0
87 #error "The darwinssl back-end requires iOS or OS X."
88 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
91 #include <sys/sysctl.h>
92 #endif /* CURL_BUILD_MAC */
96 #include "inet_pton.h"
100 #include "curl_darwinssl.h"
102 #define _MPRINTF_REPLACE /* use our functions only */
103 #include <curl/mprintf.h>
105 #include "curl_memory.h"
106 /* The last #include file should be: */
107 #include "memdebug.h"
109 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
113 /* The following two functions were ripped from Apple sample code,
114 * with some modifications: */
115 static OSStatus SocketRead(SSLConnectionRef connection,
116 void *data, /* owned by
119 size_t *dataLength) /* IN/OUT */
121 size_t bytesToGo = *dataLength;
122 size_t initLen = bytesToGo;
123 UInt8 *currData = (UInt8 *)data;
124 /*int sock = *(int *)connection;*/
125 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
126 int sock = connssl->ssl_sockfd;
127 OSStatus rtn = noErr;
136 rrtn = read(sock, currData, bytesToGo);
138 /* this is guesswork... */
140 if(rrtn == 0) { /* EOF = server hung up */
141 /* the framework will turn this into errSSLClosedNoNotify */
142 rtn = errSSLClosedGraceful;
144 else /* do the switch */
147 /* connection closed */
148 rtn = errSSLClosedGraceful;
151 rtn = errSSLClosedAbort;
154 rtn = errSSLWouldBlock;
155 connssl->ssl_direction = false;
166 bytesToGo -= bytesRead;
167 currData += bytesRead;
170 /* filled buffer with incoming data, done */
174 *dataLength = initLen - bytesToGo;
179 static OSStatus SocketWrite(SSLConnectionRef connection,
181 size_t *dataLength) /* IN/OUT */
183 size_t bytesSent = 0;
184 /*int sock = *(int *)connection;*/
185 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
186 int sock = connssl->ssl_sockfd;
188 size_t dataLen = *dataLength;
189 const UInt8 *dataPtr = (UInt8 *)data;
197 (char*)dataPtr + bytesSent,
198 dataLen - bytesSent);
199 } while((length > 0) &&
200 ( (bytesSent += length) < dataLen) );
204 if(theErr == EAGAIN) {
205 ortn = errSSLWouldBlock;
206 connssl->ssl_direction = true;
215 *dataLength = bytesSent;
219 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
221 /* SSL version 3.0 */
222 case SSL_RSA_WITH_NULL_MD5:
223 return "SSL_RSA_WITH_NULL_MD5";
225 case SSL_RSA_WITH_NULL_SHA:
226 return "SSL_RSA_WITH_NULL_SHA";
228 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
229 return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
231 case SSL_RSA_WITH_RC4_128_MD5:
232 return "SSL_RSA_WITH_RC4_128_MD5";
234 case SSL_RSA_WITH_RC4_128_SHA:
235 return "SSL_RSA_WITH_RC4_128_SHA";
237 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
238 return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
240 case SSL_RSA_WITH_IDEA_CBC_SHA:
241 return "SSL_RSA_WITH_IDEA_CBC_SHA";
243 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
244 return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
246 case SSL_RSA_WITH_DES_CBC_SHA:
247 return "SSL_RSA_WITH_DES_CBC_SHA";
249 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
250 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
252 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
253 return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
255 case SSL_DH_DSS_WITH_DES_CBC_SHA:
256 return "SSL_DH_DSS_WITH_DES_CBC_SHA";
258 case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
259 return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
261 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
262 return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
264 case SSL_DH_RSA_WITH_DES_CBC_SHA:
265 return "SSL_DH_RSA_WITH_DES_CBC_SHA";
267 case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
268 return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
270 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
271 return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
273 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
274 return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
276 case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
277 return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
279 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
280 return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
282 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
283 return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
285 case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
286 return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
288 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
289 return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
291 case SSL_DH_anon_WITH_RC4_128_MD5:
292 return "SSL_DH_anon_WITH_RC4_128_MD5";
294 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
295 return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
297 case SSL_DH_anon_WITH_DES_CBC_SHA:
298 return "SSL_DH_anon_WITH_DES_CBC_SHA";
300 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
301 return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
303 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
304 return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
306 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
307 return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
309 /* TLS 1.0 with AES (RFC 3268)
310 (Apparently these are used in SSLv3 implementations as well.) */
311 case TLS_RSA_WITH_AES_128_CBC_SHA:
312 return "TLS_RSA_WITH_AES_128_CBC_SHA";
314 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
315 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
317 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
318 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
320 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
321 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
323 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
324 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
326 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
327 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
329 case TLS_RSA_WITH_AES_256_CBC_SHA:
330 return "TLS_RSA_WITH_AES_256_CBC_SHA";
332 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
333 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
335 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
336 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
338 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
339 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
341 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
342 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
344 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
345 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
347 /* SSL version 2.0 */
348 case SSL_RSA_WITH_RC2_CBC_MD5:
349 return "SSL_RSA_WITH_RC2_CBC_MD5";
351 case SSL_RSA_WITH_IDEA_CBC_MD5:
352 return "SSL_RSA_WITH_IDEA_CBC_MD5";
354 case SSL_RSA_WITH_DES_CBC_MD5:
355 return "SSL_RSA_WITH_DES_CBC_MD5";
357 case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
358 return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
361 return "SSL_NULL_WITH_NULL_NULL";
364 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
366 /* TLS 1.0 with AES (RFC 3268) */
367 case TLS_RSA_WITH_AES_128_CBC_SHA:
368 return "TLS_RSA_WITH_AES_128_CBC_SHA";
370 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
371 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
373 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
374 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
376 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
377 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
379 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
380 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
382 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
383 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
385 case TLS_RSA_WITH_AES_256_CBC_SHA:
386 return "TLS_RSA_WITH_AES_256_CBC_SHA";
388 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
389 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
391 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
392 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
394 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
395 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
397 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
398 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
400 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
401 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
403 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
404 /* TLS 1.0 with ECDSA (RFC 4492) */
405 case TLS_ECDH_ECDSA_WITH_NULL_SHA:
406 return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
408 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
409 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
411 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
412 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
414 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
415 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
417 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
418 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
420 case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
421 return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
423 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
424 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
426 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
427 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
429 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
430 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
432 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
433 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
435 case TLS_ECDH_RSA_WITH_NULL_SHA:
436 return "TLS_ECDH_RSA_WITH_NULL_SHA";
438 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
439 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
441 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
442 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
444 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
445 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
447 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
448 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
450 case TLS_ECDHE_RSA_WITH_NULL_SHA:
451 return "TLS_ECDHE_RSA_WITH_NULL_SHA";
453 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
454 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
456 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
457 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
459 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
460 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
462 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
463 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
465 case TLS_ECDH_anon_WITH_NULL_SHA:
466 return "TLS_ECDH_anon_WITH_NULL_SHA";
468 case TLS_ECDH_anon_WITH_RC4_128_SHA:
469 return "TLS_ECDH_anon_WITH_RC4_128_SHA";
471 case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
472 return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
474 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
475 return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
477 case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
478 return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
480 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
481 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
482 /* TLS 1.2 (RFC 5246) */
483 case TLS_RSA_WITH_NULL_MD5:
484 return "TLS_RSA_WITH_NULL_MD5";
486 case TLS_RSA_WITH_NULL_SHA:
487 return "TLS_RSA_WITH_NULL_SHA";
489 case TLS_RSA_WITH_RC4_128_MD5:
490 return "TLS_RSA_WITH_RC4_128_MD5";
492 case TLS_RSA_WITH_RC4_128_SHA:
493 return "TLS_RSA_WITH_RC4_128_SHA";
495 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
496 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
498 case TLS_RSA_WITH_NULL_SHA256:
499 return "TLS_RSA_WITH_NULL_SHA256";
501 case TLS_RSA_WITH_AES_128_CBC_SHA256:
502 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
504 case TLS_RSA_WITH_AES_256_CBC_SHA256:
505 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
507 case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
508 return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
510 case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
511 return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
513 case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
514 return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
516 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
517 return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
519 case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
520 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
522 case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
523 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
525 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
526 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
528 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
529 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
531 case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
532 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
534 case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
535 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
537 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
538 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
540 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
541 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
543 case TLS_DH_anon_WITH_RC4_128_MD5:
544 return "TLS_DH_anon_WITH_RC4_128_MD5";
546 case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
547 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
549 case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
550 return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
552 case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
553 return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
555 /* TLS 1.2 with AES GCM (RFC 5288) */
556 case TLS_RSA_WITH_AES_128_GCM_SHA256:
557 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
559 case TLS_RSA_WITH_AES_256_GCM_SHA384:
560 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
562 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
563 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
565 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
566 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
568 case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
569 return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
571 case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
572 return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
574 case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
575 return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
577 case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
578 return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
580 case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
581 return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
583 case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
584 return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
586 case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
587 return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
589 case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
590 return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
592 /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
593 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
594 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
596 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
597 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
599 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
600 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
602 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
603 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
605 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
606 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
608 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
609 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
611 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
612 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
614 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
615 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
617 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
618 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
620 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
621 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
623 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
624 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
626 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
627 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
629 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
630 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
632 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
633 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
635 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
636 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
638 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
639 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
641 case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
642 return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
645 case SSL_RSA_WITH_NULL_MD5:
646 return "TLS_RSA_WITH_NULL_MD5";
648 case SSL_RSA_WITH_NULL_SHA:
649 return "TLS_RSA_WITH_NULL_SHA";
651 case SSL_RSA_WITH_RC4_128_MD5:
652 return "TLS_RSA_WITH_RC4_128_MD5";
654 case SSL_RSA_WITH_RC4_128_SHA:
655 return "TLS_RSA_WITH_RC4_128_SHA";
657 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
658 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
660 case SSL_DH_anon_WITH_RC4_128_MD5:
661 return "TLS_DH_anon_WITH_RC4_128_MD5";
663 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
664 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
666 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
667 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
668 /* TLS PSK (RFC 4279): */
669 case TLS_PSK_WITH_RC4_128_SHA:
670 return "TLS_PSK_WITH_RC4_128_SHA";
672 case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
673 return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
675 case TLS_PSK_WITH_AES_128_CBC_SHA:
676 return "TLS_PSK_WITH_AES_128_CBC_SHA";
678 case TLS_PSK_WITH_AES_256_CBC_SHA:
679 return "TLS_PSK_WITH_AES_256_CBC_SHA";
681 case TLS_DHE_PSK_WITH_RC4_128_SHA:
682 return "TLS_DHE_PSK_WITH_RC4_128_SHA";
684 case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
685 return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
687 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
688 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
690 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
691 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
693 case TLS_RSA_PSK_WITH_RC4_128_SHA:
694 return "TLS_RSA_PSK_WITH_RC4_128_SHA";
696 case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
697 return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
699 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
700 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
702 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
703 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
705 /* More TLS PSK (RFC 4785): */
706 case TLS_PSK_WITH_NULL_SHA:
707 return "TLS_PSK_WITH_NULL_SHA";
709 case TLS_DHE_PSK_WITH_NULL_SHA:
710 return "TLS_DHE_PSK_WITH_NULL_SHA";
712 case TLS_RSA_PSK_WITH_NULL_SHA:
713 return "TLS_RSA_PSK_WITH_NULL_SHA";
715 /* Even more TLS PSK (RFC 5487): */
716 case TLS_PSK_WITH_AES_128_GCM_SHA256:
717 return "TLS_PSK_WITH_AES_128_GCM_SHA256";
719 case TLS_PSK_WITH_AES_256_GCM_SHA384:
720 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
722 case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
723 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
725 case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
726 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
728 case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
729 return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
731 case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
732 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
734 case TLS_PSK_WITH_AES_128_CBC_SHA256:
735 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
737 case TLS_PSK_WITH_AES_256_CBC_SHA384:
738 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
740 case TLS_PSK_WITH_NULL_SHA256:
741 return "TLS_PSK_WITH_NULL_SHA256";
743 case TLS_PSK_WITH_NULL_SHA384:
744 return "TLS_PSK_WITH_NULL_SHA384";
746 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
747 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
749 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
750 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
752 case TLS_DHE_PSK_WITH_NULL_SHA256:
753 return "TLS_DHE_PSK_WITH_NULL_SHA256";
755 case TLS_DHE_PSK_WITH_NULL_SHA384:
756 return "TLS_RSA_PSK_WITH_NULL_SHA384";
758 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
759 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
761 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
762 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
764 case TLS_RSA_PSK_WITH_NULL_SHA256:
765 return "TLS_RSA_PSK_WITH_NULL_SHA256";
767 case TLS_RSA_PSK_WITH_NULL_SHA384:
768 return "TLS_RSA_PSK_WITH_NULL_SHA384";
770 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
772 return "TLS_NULL_WITH_NULL_NULL";
776 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
780 size_t os_version_len;
781 char *os_version_major, *os_version_minor/*, *os_version_point*/;
783 /* Get the Darwin kernel version from the kernel using sysctl(): */
785 mib[1] = KERN_OSRELEASE;
786 if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
788 os_version = malloc(os_version_len*sizeof(char));
791 if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
796 /* Parse the version: */
797 os_version_major = strtok(os_version, ".");
798 os_version_minor = strtok(NULL, ".");
799 /*os_version_point = strtok(NULL, ".");*/
800 *major = atoi(os_version_major);
801 *minor = atoi(os_version_minor);
804 #endif /* CURL_BUILD_MAC */
806 /* Apple provides a myriad of ways of getting information about a certificate
807 into a string. Some aren't available under iOS or newer cats. So here's
808 a unified function for getting a string describing the certificate that
809 ought to work in all cats starting with Leopard. */
810 CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
812 CFStringRef server_cert_summary = CFSTR("(null)");
815 /* iOS: There's only one way to do this. */
816 server_cert_summary = SecCertificateCopySubjectSummary(cert);
818 #if CURL_BUILD_MAC_10_7
819 /* Lion & later: Get the long description if we can. */
820 if(SecCertificateCopyLongDescription != NULL)
821 server_cert_summary =
822 SecCertificateCopyLongDescription(NULL, cert, NULL);
824 #endif /* CURL_BUILD_MAC_10_7 */
825 #if CURL_BUILD_MAC_10_6
826 /* Snow Leopard: Get the certificate summary. */
827 if(SecCertificateCopySubjectSummary != NULL)
828 server_cert_summary = SecCertificateCopySubjectSummary(cert);
830 #endif /* CURL_BUILD_MAC_10_6 */
831 /* Leopard is as far back as we go... */
832 (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
833 #endif /* CURL_BUILD_IOS */
834 return server_cert_summary;
837 #if CURL_SUPPORT_MAC_10_6
838 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
839 deprecation warnings, so let's not compile this unless it's necessary: */
840 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
841 SecIdentityRef *out_c_a_k)
843 OSStatus status = errSecItemNotFound;
844 SecKeychainAttributeList attr_list;
845 SecKeychainAttribute attr;
846 SecKeychainSearchRef search = NULL;
847 SecCertificateRef cert = NULL;
849 /* Set up the attribute list: */
850 attr_list.count = 1L;
851 attr_list.attr = &attr;
853 /* Set up our lone search criterion: */
854 attr.tag = kSecLabelItemAttr;
856 attr.length = (UInt32)strlen(label);
858 /* Start searching: */
859 status = SecKeychainSearchCreateFromAttributes(NULL,
860 kSecCertificateItemClass,
863 if(status == noErr) {
864 status = SecKeychainSearchCopyNext(search,
865 (SecKeychainItemRef *)&cert);
866 if(status == noErr && cert) {
867 /* If we found a certificate, does it have a private key? */
868 status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
877 #endif /* CURL_SUPPORT_MAC_10_6 */
879 static OSStatus CopyIdentityWithLabel(char *label,
880 SecIdentityRef *out_cert_and_key)
882 OSStatus status = errSecItemNotFound;
884 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
885 /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
886 kSecClassIdentity was introduced in Lion. If both exist, let's use them
887 to find the certificate. */
888 if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
891 CFDictionaryRef query_dict;
892 CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
893 kCFStringEncodingUTF8);
895 /* Set up our search criteria and expected results: */
896 values[0] = kSecClassIdentity; /* we want a certificate and a key */
898 values[1] = kCFBooleanTrue; /* we want a reference */
899 keys[1] = kSecReturnRef;
900 values[2] = kSecMatchLimitOne; /* one is enough, thanks */
901 keys[2] = kSecMatchLimit;
902 /* identity searches need a SecPolicyRef in order to work */
903 values[3] = SecPolicyCreateSSL(false, label_cf);
904 keys[3] = kSecMatchPolicy;
905 query_dict = CFDictionaryCreate(NULL, (const void **)keys,
906 (const void **)values, 4L,
907 &kCFCopyStringDictionaryKeyCallBacks,
908 &kCFTypeDictionaryValueCallBacks);
909 CFRelease(values[3]);
912 /* Do we have a match? */
913 status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
914 CFRelease(query_dict);
917 #if CURL_SUPPORT_MAC_10_6
918 /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
919 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
920 #endif /* CURL_SUPPORT_MAC_10_7 */
922 #elif CURL_SUPPORT_MAC_10_6
923 /* For developers building on older cats, we have no choice but to fall back
924 to SecKeychainSearch. */
925 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
926 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
930 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
931 const char *cPassword,
932 SecIdentityRef *out_cert_and_key)
934 OSStatus status = errSecItemNotFound;
935 CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
936 (const UInt8 *)cPath, strlen(cPath), false);
937 CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
938 cPassword, kCFStringEncodingUTF8) : NULL;
939 CFDataRef pkcs_data = NULL;
941 /* We can import P12 files on iOS or OS X 10.7 or later: */
942 /* These constants are documented as having first appeared in 10.6 but they
943 raise linker errors when used on that cat for some reason. */
944 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
945 if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
946 NULL, NULL, &status)) {
947 const void *cKeys[] = {kSecImportExportPassphrase};
948 const void *cValues[] = {password};
949 CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
950 password ? 1L : 0L, NULL, NULL);
951 CFArrayRef items = NULL;
954 status = SecPKCS12Import(pkcs_data, options, &items);
955 if(status == noErr && items && CFArrayGetCount(items)) {
956 CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
957 const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
958 kSecImportItemIdentity);
960 /* Retain the identity; we don't care about any other data... */
961 CFRetain(temp_identity);
962 *out_cert_and_key = (SecIdentityRef)temp_identity;
968 CFRelease(pkcs_data);
970 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
977 /* This code was borrowed from nss.c, with some modifications:
978 * Determine whether the nickname passed in is a filename that needs to
979 * be loaded as a PEM or a regular NSS nickname.
981 * returns 1 for a file
982 * returns 0 for not a file
984 CF_INLINE bool is_file(const char *filename)
991 if(stat(filename, &st) == 0)
992 return S_ISREG(st.st_mode);
996 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
999 struct SessionHandle *data = conn->data;
1000 curl_socket_t sockfd = conn->sock[sockindex];
1001 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1003 struct in6_addr addr;
1005 struct in_addr addr;
1006 #endif /* ENABLE_IPV6 */
1007 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1008 SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1009 char *ssl_sessionid;
1010 size_t ssl_sessionid_len;
1011 OSStatus err = noErr;
1013 int darwinver_maj = 0, darwinver_min = 0;
1015 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1016 #endif /* CURL_BUILD_MAC */
1018 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1019 if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
1020 if(connssl->ssl_ctx)
1021 CFRelease(connssl->ssl_ctx);
1022 connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1023 if(!connssl->ssl_ctx) {
1024 failf(data, "SSL: couldn't create a context!");
1025 return CURLE_OUT_OF_MEMORY;
1029 /* The old ST API does not exist under iOS, so don't compile it: */
1030 #if CURL_SUPPORT_MAC_10_8
1031 if(connssl->ssl_ctx)
1032 (void)SSLDisposeContext(connssl->ssl_ctx);
1033 err = SSLNewContext(false, &(connssl->ssl_ctx));
1035 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1036 return CURLE_OUT_OF_MEMORY;
1038 #endif /* CURL_SUPPORT_MAC_10_8 */
1041 if(connssl->ssl_ctx)
1042 (void)SSLDisposeContext(connssl->ssl_ctx);
1043 err = SSLNewContext(false, &(connssl->ssl_ctx));
1045 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1046 return CURLE_OUT_OF_MEMORY;
1048 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1049 connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1051 /* check to see if we've been told to use an explicit SSL/TLS version */
1052 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1053 if(SSLSetProtocolVersionMax != NULL) {
1054 switch(data->set.ssl.version) {
1055 case CURL_SSLVERSION_DEFAULT: default:
1056 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1057 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1059 case CURL_SSLVERSION_TLSv1:
1060 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1061 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1063 case CURL_SSLVERSION_TLSv1_0:
1064 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1065 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
1067 case CURL_SSLVERSION_TLSv1_1:
1068 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
1069 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
1071 case CURL_SSLVERSION_TLSv1_2:
1072 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
1073 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1075 case CURL_SSLVERSION_SSLv3:
1076 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1077 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
1079 case CURL_SSLVERSION_SSLv2:
1080 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
1082 failf(data, "Your version of the OS does not support SSLv2");
1083 return CURLE_SSL_CONNECT_ERROR;
1085 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
1089 #if CURL_SUPPORT_MAC_10_8
1090 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1093 switch (data->set.ssl.version) {
1094 case CURL_SSLVERSION_DEFAULT: default:
1095 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1098 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1101 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1104 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1108 case CURL_SSLVERSION_TLSv1:
1109 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1112 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1115 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1119 case CURL_SSLVERSION_TLSv1_0:
1120 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1124 case CURL_SSLVERSION_TLSv1_1:
1125 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1129 case CURL_SSLVERSION_TLSv1_2:
1130 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1134 case CURL_SSLVERSION_SSLv3:
1135 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
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 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1159 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1163 case CURL_SSLVERSION_TLSv1:
1164 case CURL_SSLVERSION_TLSv1_0:
1165 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1169 case CURL_SSLVERSION_TLSv1_1:
1170 failf(data, "Your version of the OS does not support TLSv1.1");
1171 return CURLE_SSL_CONNECT_ERROR;
1172 case CURL_SSLVERSION_TLSv1_2:
1173 failf(data, "Your version of the OS does not support TLSv1.2");
1174 return CURLE_SSL_CONNECT_ERROR;
1175 case CURL_SSLVERSION_SSLv2:
1176 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1180 failf(data, "Your version of the OS does not support SSLv2");
1181 return CURLE_SSL_CONNECT_ERROR;
1184 case CURL_SSLVERSION_SSLv3:
1185 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1190 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1192 if(data->set.str[STRING_KEY]) {
1193 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1194 "Transport. The private key must be in the Keychain.\n");
1197 if(data->set.str[STRING_CERT]) {
1198 SecIdentityRef cert_and_key = NULL;
1199 bool is_cert_file = is_file(data->set.str[STRING_CERT]);
1201 /* User wants to authenticate with a client cert. Look for it:
1202 If we detect that this is a file on disk, then let's load it.
1203 Otherwise, assume that the user wants to use an identity loaded
1204 from the Keychain. */
1206 if(!data->set.str[STRING_CERT_TYPE])
1207 infof(data, "WARNING: SSL: Certificate type not set, assuming "
1208 "PKCS#12 format.\n");
1209 else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
1210 strlen(data->set.str[STRING_CERT_TYPE])) != 0)
1211 infof(data, "WARNING: SSL: The Security framework only supports "
1212 "loading identities that are in PKCS#12 format.\n");
1214 err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
1215 data->set.str[STRING_KEY_PASSWD], &cert_and_key);
1218 err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
1221 SecCertificateRef cert = NULL;
1222 CFTypeRef certs_c[1];
1225 /* If we found one, print it out: */
1226 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1228 CFStringRef cert_summary = CopyCertSubject(cert);
1229 char cert_summary_c[128];
1232 memset(cert_summary_c, 0, 128);
1233 if(CFStringGetCString(cert_summary,
1236 kCFStringEncodingUTF8)) {
1237 infof(data, "Client certificate: %s\n", cert_summary_c);
1239 CFRelease(cert_summary);
1243 certs_c[0] = cert_and_key;
1244 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1245 &kCFTypeArrayCallBacks);
1246 err = SSLSetCertificate(connssl->ssl_ctx, certs);
1250 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1251 return CURLE_SSL_CERTPROBLEM;
1253 CFRelease(cert_and_key);
1257 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1258 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1259 "and its private key.", data->set.str[STRING_CERT]);
1261 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1262 failf(data, "SSL: Couldn't make sense of the data in the "
1263 "certificate \"%s\" and its private key.",
1264 data->set.str[STRING_CERT]);
1266 case -25260: /* errSecPassphraseRequired */
1267 failf(data, "SSL The certificate \"%s\" requires a password.",
1268 data->set.str[STRING_CERT]);
1270 case errSecItemNotFound:
1271 failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1272 "key in the Keychain.", data->set.str[STRING_CERT]);
1275 failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1276 "key: OSStatus %d", data->set.str[STRING_CERT], err);
1279 return CURLE_SSL_CERTPROBLEM;
1283 /* SSL always tries to verify the peer, this only says whether it should
1284 * fail to connect if the verification fails, or if it should continue
1285 * anyway. In the latter case the result of the verification is checked with
1286 * SSL_get_verify_result() below. */
1287 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1288 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1289 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1290 works, it doesn't work as expected under Snow Leopard or Lion.
1291 So we need to call SSLSetEnableCertVerify() on those older cats in order
1292 to disable certificate validation if the user turned that off.
1293 (SecureTransport will always validate the certificate chain by
1295 /* (Note: Darwin 12.x.x is Mountain Lion.) */
1297 if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
1299 if(SSLSetSessionOption != NULL) {
1300 #endif /* CURL_BUILD_MAC */
1301 err = SSLSetSessionOption(connssl->ssl_ctx,
1302 kSSLSessionOptionBreakOnServerAuth,
1303 data->set.ssl.verifypeer?false:true);
1305 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1306 return CURLE_SSL_CONNECT_ERROR;
1310 #if CURL_SUPPORT_MAC_10_8
1311 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1312 data->set.ssl.verifypeer?true:false);
1314 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1315 return CURLE_SSL_CONNECT_ERROR;
1317 #endif /* CURL_SUPPORT_MAC_10_8 */
1320 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1321 data->set.ssl.verifypeer?true:false);
1323 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1324 return CURLE_SSL_CONNECT_ERROR;
1326 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1328 /* Configure hostname check. SNI is used if available.
1329 * Both hostname check and SNI require SSLSetPeerDomainName().
1330 * Also: the verifyhost setting influences SNI usage */
1331 if(data->set.ssl.verifyhost) {
1332 err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1333 strlen(conn->host.name));
1336 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1340 if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
1342 || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
1345 infof(data, "WARNING: using IP address, SNI is being disabled by "
1350 /* Disable cipher suites that ST supports but are not safe. These ciphers
1351 are unlikely to be used in any case since ST gives other ciphers a much
1352 higher priority, but it's probably better that we not connect at all than
1353 to give the user a false sense of security if the server only supports
1354 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1355 (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1356 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1357 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1358 if(all_ciphers && allowed_ciphers &&
1359 SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1360 &all_ciphers_count) == noErr) {
1361 for(i = 0UL ; i < all_ciphers_count ; i++) {
1363 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1364 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1365 Work around the problem here by disabling those ciphers if we are
1366 running in an affected version of OS X. */
1367 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1368 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1371 #endif /* CURL_BUILD_MAC */
1372 switch(all_ciphers[i]) {
1373 /* Disable NULL ciphersuites: */
1374 case SSL_NULL_WITH_NULL_NULL:
1375 case SSL_RSA_WITH_NULL_MD5:
1376 case SSL_RSA_WITH_NULL_SHA:
1377 case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1378 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1379 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1380 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1381 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1382 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1383 case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1384 case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1385 case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1386 case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1387 case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1388 case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1389 case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1390 case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1391 case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1392 /* Disable anonymous ciphersuites: */
1393 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1394 case SSL_DH_anon_WITH_RC4_128_MD5:
1395 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1396 case SSL_DH_anon_WITH_DES_CBC_SHA:
1397 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1398 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1399 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1400 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1401 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1402 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1403 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1404 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1405 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1406 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1407 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1408 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1409 /* Disable weak key ciphersuites: */
1410 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1411 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1412 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1413 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1414 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1415 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1416 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1417 case SSL_RSA_WITH_DES_CBC_SHA:
1418 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1419 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1420 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1421 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1423 case SSL_RSA_WITH_IDEA_CBC_SHA:
1424 case SSL_RSA_WITH_IDEA_CBC_MD5:
1426 default: /* enable everything else */
1427 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1431 err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1432 allowed_ciphers_count);
1434 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1435 return CURLE_SSL_CONNECT_ERROR;
1439 Curl_safefree(all_ciphers);
1440 Curl_safefree(allowed_ciphers);
1441 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1442 return CURLE_OUT_OF_MEMORY;
1444 Curl_safefree(all_ciphers);
1445 Curl_safefree(allowed_ciphers);
1447 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1448 /* We want to enable 1/n-1 when using a CBC cipher unless the user
1449 specifically doesn't want us doing that: */
1450 if(SSLSetSessionOption != NULL)
1451 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1452 !data->set.ssl_enable_beast);
1453 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1455 /* Check if there's a cached ID we can/should use here! */
1456 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1457 &ssl_sessionid_len)) {
1458 /* we got a session id, use it! */
1459 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1461 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1462 return CURLE_SSL_CONNECT_ERROR;
1464 /* Informational message */
1465 infof(data, "SSL re-using session ID\n");
1467 /* If there isn't one, then let's make one up! This has to be done prior
1468 to starting the handshake. */
1472 ssl_sessionid = malloc(256*sizeof(char));
1473 ssl_sessionid_len = snprintf(ssl_sessionid, 256, "curl:%s:%hu",
1474 conn->host.name, conn->remote_port);
1475 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1477 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1478 return CURLE_SSL_CONNECT_ERROR;
1480 retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1481 if(retcode!= CURLE_OK) {
1482 failf(data, "failed to store ssl session");
1487 err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1489 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1490 return CURLE_SSL_CONNECT_ERROR;
1493 /* pass the raw socket into the SSL layers */
1494 /* We need to store the FD in a constant memory address, because
1495 * SSLSetConnection() will not copy that address. I've found that
1496 * conn->sock[sockindex] may change on its own. */
1497 connssl->ssl_sockfd = sockfd;
1498 err = SSLSetConnection(connssl->ssl_ctx, connssl);
1500 failf(data, "SSL: SSLSetConnection() failed: %d", err);
1501 return CURLE_SSL_CONNECT_ERROR;
1504 connssl->connecting_state = ssl_connect_2;
1509 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1511 struct SessionHandle *data = conn->data;
1512 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1514 SSLCipherSuite cipher;
1515 SSLProtocol protocol = 0;
1517 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1518 || ssl_connect_2_reading == connssl->connecting_state
1519 || ssl_connect_2_writing == connssl->connecting_state);
1521 /* Here goes nothing: */
1522 err = SSLHandshake(connssl->ssl_ctx);
1526 case errSSLWouldBlock: /* they're not done with us yet */
1527 connssl->connecting_state = connssl->ssl_direction ?
1528 ssl_connect_2_writing : ssl_connect_2_reading;
1531 /* The below is errSSLServerAuthCompleted; it's not defined in
1532 Leopard's headers */
1534 /* the documentation says we need to call SSLHandshake() again */
1535 return darwinssl_connect_step2(conn, sockindex);
1537 /* These are all certificate problems with the server: */
1538 case errSSLXCertChainInvalid:
1539 failf(data, "SSL certificate problem: Invalid certificate chain");
1540 return CURLE_SSL_CACERT;
1541 case errSSLUnknownRootCert:
1542 failf(data, "SSL certificate problem: Untrusted root certificate");
1543 return CURLE_SSL_CACERT;
1544 case errSSLNoRootCert:
1545 failf(data, "SSL certificate problem: No root certificate");
1546 return CURLE_SSL_CACERT;
1547 case errSSLCertExpired:
1548 failf(data, "SSL certificate problem: Certificate chain had an "
1549 "expired certificate");
1550 return CURLE_SSL_CACERT;
1552 failf(data, "SSL certificate problem: Couldn't understand the server "
1553 "certificate format");
1554 return CURLE_SSL_CONNECT_ERROR;
1556 /* These are all certificate problems with the client: */
1557 case errSecAuthFailed:
1558 failf(data, "SSL authentication failed");
1559 return CURLE_SSL_CONNECT_ERROR;
1560 case errSSLPeerHandshakeFail:
1561 failf(data, "SSL peer handshake failed, the server most likely "
1562 "requires a client certificate to connect");
1563 return CURLE_SSL_CONNECT_ERROR;
1564 case errSSLPeerUnknownCA:
1565 failf(data, "SSL server rejected the client certificate due to "
1566 "the certificate being signed by an unknown certificate "
1568 return CURLE_SSL_CONNECT_ERROR;
1570 /* This error is raised if the server's cert didn't match the server's
1572 case errSSLHostNameMismatch:
1573 failf(data, "SSL certificate peer verification failed, the "
1574 "certificate did not match \"%s\"\n", conn->host.dispname);
1575 return CURLE_PEER_FAILED_VERIFICATION;
1577 /* Generic handshake errors: */
1578 case errSSLConnectionRefused:
1579 failf(data, "Server dropped the connection during the SSL handshake");
1580 return CURLE_SSL_CONNECT_ERROR;
1581 case errSSLClosedAbort:
1582 failf(data, "Server aborted the SSL handshake");
1583 return CURLE_SSL_CONNECT_ERROR;
1584 case errSSLNegotiation:
1585 failf(data, "Could not negotiate an SSL cipher suite with the server");
1586 return CURLE_SSL_CONNECT_ERROR;
1587 /* Sometimes paramErr happens with buggy ciphers: */
1588 case paramErr: case errSSLInternal:
1589 failf(data, "Internal SSL engine error encountered during the "
1591 return CURLE_SSL_CONNECT_ERROR;
1592 case errSSLFatalAlert:
1593 failf(data, "Fatal SSL engine error encountered during the SSL "
1595 return CURLE_SSL_CONNECT_ERROR;
1597 failf(data, "Unknown SSL protocol error in connection to %s:%d",
1598 conn->host.name, err);
1599 return CURLE_SSL_CONNECT_ERROR;
1603 /* we have been connected fine, we're not waiting for anything else. */
1604 connssl->connecting_state = ssl_connect_3;
1606 /* Informational message */
1607 (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1608 (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1611 infof(data, "SSL 2.0 connection using %s\n",
1612 SSLCipherNameForNumber(cipher));
1615 infof(data, "SSL 3.0 connection using %s\n",
1616 SSLCipherNameForNumber(cipher));
1619 infof(data, "TLS 1.0 connection using %s\n",
1620 TLSCipherNameForNumber(cipher));
1622 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1623 case kTLSProtocol11:
1624 infof(data, "TLS 1.1 connection using %s\n",
1625 TLSCipherNameForNumber(cipher));
1627 case kTLSProtocol12:
1628 infof(data, "TLS 1.2 connection using %s\n",
1629 TLSCipherNameForNumber(cipher));
1633 infof(data, "Unknown protocol connection\n");
1642 darwinssl_connect_step3(struct connectdata *conn,
1645 struct SessionHandle *data = conn->data;
1646 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1647 CFStringRef server_cert_summary;
1648 char server_cert_summary_c[128];
1649 CFArrayRef server_certs = NULL;
1650 SecCertificateRef server_cert;
1653 SecTrustRef trust = NULL;
1655 /* There is no step 3!
1656 * Well, okay, if verbose mode is on, let's print the details of the
1657 * server certificates. */
1658 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1660 #pragma unused(server_certs)
1661 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1662 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1663 a null trust, so be on guard for that: */
1664 if(err == noErr && trust) {
1665 count = SecTrustGetCertificateCount(trust);
1666 for(i = 0L ; i < count ; i++) {
1667 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1668 server_cert_summary = CopyCertSubject(server_cert);
1669 memset(server_cert_summary_c, 0, 128);
1670 if(CFStringGetCString(server_cert_summary,
1671 server_cert_summary_c,
1673 kCFStringEncodingUTF8)) {
1674 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1676 CFRelease(server_cert_summary);
1681 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
1682 The function SecTrustGetCertificateAtIndex() is officially present
1683 in Lion, but it is unfortunately also present in Snow Leopard as
1684 private API and doesn't work as expected. So we have to look for
1685 a different symbol to make sure this code is only executed under
1687 if(SecTrustEvaluateAsync != NULL) {
1688 #pragma unused(server_certs)
1689 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1690 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1691 a null trust, so be on guard for that: */
1692 if(err == noErr && trust) {
1693 count = SecTrustGetCertificateCount(trust);
1694 for(i = 0L ; i < count ; i++) {
1695 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1696 server_cert_summary = CopyCertSubject(server_cert);
1697 memset(server_cert_summary_c, 0, 128);
1698 if(CFStringGetCString(server_cert_summary,
1699 server_cert_summary_c,
1701 kCFStringEncodingUTF8)) {
1702 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1704 CFRelease(server_cert_summary);
1710 #if CURL_SUPPORT_MAC_10_8
1711 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1712 /* Just in case SSLCopyPeerCertificates() returns null too... */
1713 if(err == noErr && server_certs) {
1714 count = CFArrayGetCount(server_certs);
1715 for(i = 0L ; i < count ; i++) {
1716 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
1719 server_cert_summary = CopyCertSubject(server_cert);
1720 memset(server_cert_summary_c, 0, 128);
1721 if(CFStringGetCString(server_cert_summary,
1722 server_cert_summary_c,
1724 kCFStringEncodingUTF8)) {
1725 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1727 CFRelease(server_cert_summary);
1729 CFRelease(server_certs);
1731 #endif /* CURL_SUPPORT_MAC_10_8 */
1733 #endif /* CURL_BUILD_IOS */
1735 #pragma unused(trust)
1736 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1738 count = CFArrayGetCount(server_certs);
1739 for(i = 0L ; i < count ; i++) {
1740 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
1741 server_cert_summary = CopyCertSubject(server_cert);
1742 memset(server_cert_summary_c, 0, 128);
1743 if(CFStringGetCString(server_cert_summary,
1744 server_cert_summary_c,
1746 kCFStringEncodingUTF8)) {
1747 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1749 CFRelease(server_cert_summary);
1751 CFRelease(server_certs);
1753 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1755 connssl->connecting_state = ssl_connect_done;
1759 static Curl_recv darwinssl_recv;
1760 static Curl_send darwinssl_send;
1763 darwinssl_connect_common(struct connectdata *conn,
1769 struct SessionHandle *data = conn->data;
1770 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1771 curl_socket_t sockfd = conn->sock[sockindex];
1775 /* check if the connection has already been established */
1776 if(ssl_connection_complete == connssl->state) {
1781 if(ssl_connect_1==connssl->connecting_state) {
1782 /* Find out how much more time we're allowed */
1783 timeout_ms = Curl_timeleft(data, NULL, TRUE);
1785 if(timeout_ms < 0) {
1786 /* no need to continue if time already is up */
1787 failf(data, "SSL connection timeout");
1788 return CURLE_OPERATION_TIMEDOUT;
1790 retcode = darwinssl_connect_step1(conn, sockindex);
1795 while(ssl_connect_2 == connssl->connecting_state ||
1796 ssl_connect_2_reading == connssl->connecting_state ||
1797 ssl_connect_2_writing == connssl->connecting_state) {
1799 /* check allowed time left */
1800 timeout_ms = Curl_timeleft(data, NULL, TRUE);
1802 if(timeout_ms < 0) {
1803 /* no need to continue if time already is up */
1804 failf(data, "SSL connection timeout");
1805 return CURLE_OPERATION_TIMEDOUT;
1808 /* if ssl is expecting something, check if it's available. */
1809 if(connssl->connecting_state == ssl_connect_2_reading
1810 || connssl->connecting_state == ssl_connect_2_writing) {
1812 curl_socket_t writefd = ssl_connect_2_writing ==
1813 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1814 curl_socket_t readfd = ssl_connect_2_reading ==
1815 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1817 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
1820 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1821 return CURLE_SSL_CONNECT_ERROR;
1823 else if(0 == what) {
1830 failf(data, "SSL connection timeout");
1831 return CURLE_OPERATION_TIMEDOUT;
1834 /* socket is readable or writable */
1837 /* Run transaction, and return to the caller if it failed or if this
1838 * connection is done nonblocking and this loop would execute again. This
1839 * permits the owner of a multi handle to abort a connection attempt
1840 * before step2 has completed while ensuring that a client using select()
1841 * or epoll() will always have a valid fdset to wait on.
1843 retcode = darwinssl_connect_step2(conn, sockindex);
1844 if(retcode || (nonblocking &&
1845 (ssl_connect_2 == connssl->connecting_state ||
1846 ssl_connect_2_reading == connssl->connecting_state ||
1847 ssl_connect_2_writing == connssl->connecting_state)))
1850 } /* repeat step2 until all transactions are done. */
1853 if(ssl_connect_3==connssl->connecting_state) {
1854 retcode = darwinssl_connect_step3(conn, sockindex);
1859 if(ssl_connect_done==connssl->connecting_state) {
1860 connssl->state = ssl_connection_complete;
1861 conn->recv[sockindex] = darwinssl_recv;
1862 conn->send[sockindex] = darwinssl_send;
1868 /* Reset our connect state machine */
1869 connssl->connecting_state = ssl_connect_1;
1875 Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
1879 return darwinssl_connect_common(conn, sockindex, TRUE, done);
1883 Curl_darwinssl_connect(struct connectdata *conn,
1889 retcode = darwinssl_connect_common(conn, sockindex, FALSE, &done);
1899 void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
1901 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1903 if(connssl->ssl_ctx) {
1904 (void)SSLClose(connssl->ssl_ctx);
1905 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1906 if(SSLCreateContext != NULL)
1907 CFRelease(connssl->ssl_ctx);
1908 #if CURL_SUPPORT_MAC_10_8
1910 (void)SSLDisposeContext(connssl->ssl_ctx);
1911 #endif /* CURL_SUPPORT_MAC_10_8 */
1913 (void)SSLDisposeContext(connssl->ssl_ctx);
1914 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1915 connssl->ssl_ctx = NULL;
1917 connssl->ssl_sockfd = 0;
1920 void Curl_darwinssl_close_all(struct SessionHandle *data)
1922 /* SecureTransport doesn't separate sessions from contexts, so... */
1926 int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
1928 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1929 struct SessionHandle *data = conn->data;
1935 if(!connssl->ssl_ctx)
1938 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
1941 Curl_darwinssl_close(conn, sockindex);
1945 what = Curl_socket_ready(conn->sock[sockindex],
1946 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
1950 /* anything that gets here is fatally bad */
1951 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1956 if(!what) { /* timeout */
1957 failf(data, "SSL shutdown timeout");
1961 /* Something to read, let's do it and hope that it is the close
1962 notify alert from the server. No way to SSL_Read now, so use read(). */
1964 nread = read(conn->sock[sockindex], buf, sizeof(buf));
1967 failf(data, "read: %s", strerror(errno));
1974 what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
1980 void Curl_darwinssl_session_free(void *ptr)
1982 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
1983 cached session ID inside the Security framework. There is a private
1984 function that does this, but I don't want to have to explain to you why I
1985 got your application rejected from the App Store due to the use of a
1986 private API, so the best we can do is free up our own char array that we
1987 created way back in darwinssl_connect_step1... */
1991 size_t Curl_darwinssl_version(char *buffer, size_t size)
1993 return snprintf(buffer, size, "SecureTransport");
1997 * This function uses SSLGetSessionState to determine connection status.
2000 * 1 means the connection is still in place
2001 * 0 means the connection has been closed
2002 * -1 means the connection status is unknown
2004 int Curl_darwinssl_check_cxn(struct connectdata *conn)
2006 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2008 SSLSessionState state;
2010 if(connssl->ssl_ctx) {
2011 err = SSLGetSessionState(connssl->ssl_ctx, &state);
2013 return state == kSSLConnected || state == kSSLHandshake;
2019 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2022 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2026 if(connssl->ssl_ctx) { /* SSL is in use */
2027 err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
2029 return buffer > 0UL;
2036 void Curl_darwinssl_random(struct SessionHandle *data,
2037 unsigned char *entropy,
2040 /* arc4random_buf() isn't available on cats older than Lion, so let's
2041 do this manually for the benefit of the older cats. */
2043 u_int32_t random_number = 0;
2045 for(i = 0 ; i < length ; i++) {
2046 if(i % sizeof(u_int32_t) == 0)
2047 random_number = arc4random();
2048 entropy[i] = random_number & 0xFF;
2049 random_number >>= 8;
2051 i = random_number = 0;
2055 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2057 unsigned char *md5sum, /* output */
2061 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2064 static ssize_t darwinssl_send(struct connectdata *conn,
2070 /*struct SessionHandle *data = conn->data;*/
2071 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2072 size_t processed = 0UL;
2075 /* The SSLWrite() function works a little differently than expected. The
2076 fourth argument (processed) is currently documented in Apple's
2077 documentation as: "On return, the length, in bytes, of the data actually
2080 Now, one could interpret that as "written to the socket," but actually,
2081 it returns the amount of data that was written to a buffer internal to
2082 the SSLContextRef instead. So it's possible for SSLWrite() to return
2083 errSSLWouldBlock and a number of bytes "written" because those bytes were
2084 encrypted and written to a buffer, not to the socket.
2086 So if this happens, then we need to keep calling SSLWrite() over and
2087 over again with no new data until it quits returning errSSLWouldBlock. */
2089 /* Do we have buffered data to write from the last time we were called? */
2090 if(connssl->ssl_write_buffered_length) {
2091 /* Write the buffered data: */
2092 err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
2095 /* processed is always going to be 0 because we didn't write to
2096 the buffer, so return how much was written to the socket */
2097 processed = connssl->ssl_write_buffered_length;
2098 connssl->ssl_write_buffered_length = 0UL;
2100 case errSSLWouldBlock: /* argh, try again */
2101 *curlcode = CURLE_AGAIN;
2104 failf(conn->data, "SSLWrite() returned error %d", err);
2105 *curlcode = CURLE_SEND_ERROR;
2110 /* We've got new data to write: */
2111 err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
2114 case errSSLWouldBlock:
2115 /* Data was buffered but not sent, we have to tell the caller
2116 to try sending again, and remember how much was buffered */
2117 connssl->ssl_write_buffered_length = len;
2118 *curlcode = CURLE_AGAIN;
2121 failf(conn->data, "SSLWrite() returned error %d", err);
2122 *curlcode = CURLE_SEND_ERROR;
2127 return (ssize_t)processed;
2130 static ssize_t darwinssl_recv(struct connectdata *conn,
2136 /*struct SessionHandle *data = conn->data;*/
2137 struct ssl_connect_data *connssl = &conn->ssl[num];
2138 size_t processed = 0UL;
2139 OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
2143 case errSSLWouldBlock: /* return how much we read (if anything) */
2145 return (ssize_t)processed;
2146 *curlcode = CURLE_AGAIN;
2150 /* errSSLClosedGraceful - server gracefully shut down the SSL session
2151 errSSLClosedNoNotify - server hung up on us instead of sending a
2152 closure alert notice, read() is returning 0
2153 Either way, inform the caller that the server disconnected. */
2154 case errSSLClosedGraceful:
2155 case errSSLClosedNoNotify:
2156 *curlcode = CURLE_OK;
2161 failf(conn->data, "SSLRead() return error %d", err);
2162 *curlcode = CURLE_RECV_ERROR;
2167 return (ssize_t)processed;
2170 #endif /* USE_DARWINSSL */