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"
31 #include "urldata.h" /* for the SessionHandle definition */
32 #include "curl_base64.h"
40 #include <Security/Security.h>
41 #include <Security/SecureTransport.h>
42 #include <CoreFoundation/CoreFoundation.h>
43 #include <CommonCrypto/CommonDigest.h>
45 /* The Security framework has changed greatly between iOS and different OS X
46 versions, and we will try to support as many of them as we can (back to
47 Leopard and iOS 5) by using macros and weak-linking.
49 IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
50 you must build this project against the 10.8 SDK or later. */
51 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
53 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
54 #error "The darwinssl back-end requires Leopard or later."
55 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
57 #define CURL_BUILD_IOS 0
58 #define CURL_BUILD_IOS_7 0
59 #define CURL_BUILD_MAC 1
60 /* This is the maximum API level we are allowed to use when building: */
61 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
62 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
63 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
64 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
65 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
66 /* These macros mean "the following code is present to allow runtime backward
67 compatibility with at least this cat or earlier":
68 (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
69 environmental variable.) */
70 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
71 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
72 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
73 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
74 #define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
76 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
77 #define CURL_BUILD_IOS 1
78 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
79 #define CURL_BUILD_MAC 0
80 #define CURL_BUILD_MAC_10_5 0
81 #define CURL_BUILD_MAC_10_6 0
82 #define CURL_BUILD_MAC_10_7 0
83 #define CURL_BUILD_MAC_10_8 0
84 #define CURL_SUPPORT_MAC_10_5 0
85 #define CURL_SUPPORT_MAC_10_6 0
86 #define CURL_SUPPORT_MAC_10_7 0
87 #define CURL_SUPPORT_MAC_10_8 0
90 #error "The darwinssl back-end requires iOS or OS X."
91 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
94 #include <sys/sysctl.h>
95 #endif /* CURL_BUILD_MAC */
99 #include "inet_pton.h"
103 #include "curl_darwinssl.h"
105 #define _MPRINTF_REPLACE /* use our functions only */
106 #include <curl/mprintf.h>
108 #include "curl_memory.h"
109 /* The last #include file should be: */
110 #include "memdebug.h"
112 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
116 /* The following two functions were ripped from Apple sample code,
117 * with some modifications: */
118 static OSStatus SocketRead(SSLConnectionRef connection,
119 void *data, /* owned by
122 size_t *dataLength) /* IN/OUT */
124 size_t bytesToGo = *dataLength;
125 size_t initLen = bytesToGo;
126 UInt8 *currData = (UInt8 *)data;
127 /*int sock = *(int *)connection;*/
128 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
129 int sock = connssl->ssl_sockfd;
130 OSStatus rtn = noErr;
139 rrtn = read(sock, currData, bytesToGo);
141 /* this is guesswork... */
143 if(rrtn == 0) { /* EOF = server hung up */
144 /* the framework will turn this into errSSLClosedNoNotify */
145 rtn = errSSLClosedGraceful;
147 else /* do the switch */
150 /* connection closed */
151 rtn = errSSLClosedGraceful;
154 rtn = errSSLClosedAbort;
157 rtn = errSSLWouldBlock;
158 connssl->ssl_direction = false;
169 bytesToGo -= bytesRead;
170 currData += bytesRead;
173 /* filled buffer with incoming data, done */
177 *dataLength = initLen - bytesToGo;
182 static OSStatus SocketWrite(SSLConnectionRef connection,
184 size_t *dataLength) /* IN/OUT */
186 size_t bytesSent = 0;
187 /*int sock = *(int *)connection;*/
188 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
189 int sock = connssl->ssl_sockfd;
191 size_t dataLen = *dataLength;
192 const UInt8 *dataPtr = (UInt8 *)data;
200 (char*)dataPtr + bytesSent,
201 dataLen - bytesSent);
202 } while((length > 0) &&
203 ( (bytesSent += length) < dataLen) );
207 if(theErr == EAGAIN) {
208 ortn = errSSLWouldBlock;
209 connssl->ssl_direction = true;
218 *dataLength = bytesSent;
222 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
224 /* SSL version 3.0 */
225 case SSL_RSA_WITH_NULL_MD5:
226 return "SSL_RSA_WITH_NULL_MD5";
228 case SSL_RSA_WITH_NULL_SHA:
229 return "SSL_RSA_WITH_NULL_SHA";
231 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
232 return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
234 case SSL_RSA_WITH_RC4_128_MD5:
235 return "SSL_RSA_WITH_RC4_128_MD5";
237 case SSL_RSA_WITH_RC4_128_SHA:
238 return "SSL_RSA_WITH_RC4_128_SHA";
240 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
241 return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
243 case SSL_RSA_WITH_IDEA_CBC_SHA:
244 return "SSL_RSA_WITH_IDEA_CBC_SHA";
246 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
247 return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
249 case SSL_RSA_WITH_DES_CBC_SHA:
250 return "SSL_RSA_WITH_DES_CBC_SHA";
252 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
253 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
255 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
256 return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
258 case SSL_DH_DSS_WITH_DES_CBC_SHA:
259 return "SSL_DH_DSS_WITH_DES_CBC_SHA";
261 case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
262 return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
264 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
265 return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
267 case SSL_DH_RSA_WITH_DES_CBC_SHA:
268 return "SSL_DH_RSA_WITH_DES_CBC_SHA";
270 case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
271 return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
273 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
274 return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
276 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
277 return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
279 case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
280 return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
282 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
283 return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
285 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
286 return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
288 case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
289 return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
291 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
292 return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
294 case SSL_DH_anon_WITH_RC4_128_MD5:
295 return "SSL_DH_anon_WITH_RC4_128_MD5";
297 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
298 return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
300 case SSL_DH_anon_WITH_DES_CBC_SHA:
301 return "SSL_DH_anon_WITH_DES_CBC_SHA";
303 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
304 return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
306 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
307 return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
309 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
310 return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
312 /* TLS 1.0 with AES (RFC 3268)
313 (Apparently these are used in SSLv3 implementations as well.) */
314 case TLS_RSA_WITH_AES_128_CBC_SHA:
315 return "TLS_RSA_WITH_AES_128_CBC_SHA";
317 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
318 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
320 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
321 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
323 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
324 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
326 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
327 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
329 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
330 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
332 case TLS_RSA_WITH_AES_256_CBC_SHA:
333 return "TLS_RSA_WITH_AES_256_CBC_SHA";
335 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
336 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
338 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
339 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
341 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
342 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
344 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
345 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
347 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
348 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
350 /* SSL version 2.0 */
351 case SSL_RSA_WITH_RC2_CBC_MD5:
352 return "SSL_RSA_WITH_RC2_CBC_MD5";
354 case SSL_RSA_WITH_IDEA_CBC_MD5:
355 return "SSL_RSA_WITH_IDEA_CBC_MD5";
357 case SSL_RSA_WITH_DES_CBC_MD5:
358 return "SSL_RSA_WITH_DES_CBC_MD5";
360 case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
361 return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
364 return "SSL_NULL_WITH_NULL_NULL";
367 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
369 /* TLS 1.0 with AES (RFC 3268) */
370 case TLS_RSA_WITH_AES_128_CBC_SHA:
371 return "TLS_RSA_WITH_AES_128_CBC_SHA";
373 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
374 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
376 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
377 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
379 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
380 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
382 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
383 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
385 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
386 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
388 case TLS_RSA_WITH_AES_256_CBC_SHA:
389 return "TLS_RSA_WITH_AES_256_CBC_SHA";
391 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
392 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
394 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
395 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
397 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
398 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
400 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
401 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
403 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
404 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
406 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
407 /* TLS 1.0 with ECDSA (RFC 4492) */
408 case TLS_ECDH_ECDSA_WITH_NULL_SHA:
409 return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
411 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
412 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
414 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
415 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
417 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
418 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
420 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
421 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
423 case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
424 return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
426 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
427 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
429 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
430 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
432 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
433 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
435 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
436 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
438 case TLS_ECDH_RSA_WITH_NULL_SHA:
439 return "TLS_ECDH_RSA_WITH_NULL_SHA";
441 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
442 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
444 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
445 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
447 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
448 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
450 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
451 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
453 case TLS_ECDHE_RSA_WITH_NULL_SHA:
454 return "TLS_ECDHE_RSA_WITH_NULL_SHA";
456 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
457 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
459 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
460 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
462 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
463 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
465 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
466 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
468 case TLS_ECDH_anon_WITH_NULL_SHA:
469 return "TLS_ECDH_anon_WITH_NULL_SHA";
471 case TLS_ECDH_anon_WITH_RC4_128_SHA:
472 return "TLS_ECDH_anon_WITH_RC4_128_SHA";
474 case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
475 return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
477 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
478 return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
480 case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
481 return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
483 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
484 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
485 /* TLS 1.2 (RFC 5246) */
486 case TLS_RSA_WITH_NULL_MD5:
487 return "TLS_RSA_WITH_NULL_MD5";
489 case TLS_RSA_WITH_NULL_SHA:
490 return "TLS_RSA_WITH_NULL_SHA";
492 case TLS_RSA_WITH_RC4_128_MD5:
493 return "TLS_RSA_WITH_RC4_128_MD5";
495 case TLS_RSA_WITH_RC4_128_SHA:
496 return "TLS_RSA_WITH_RC4_128_SHA";
498 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
499 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
501 case TLS_RSA_WITH_NULL_SHA256:
502 return "TLS_RSA_WITH_NULL_SHA256";
504 case TLS_RSA_WITH_AES_128_CBC_SHA256:
505 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
507 case TLS_RSA_WITH_AES_256_CBC_SHA256:
508 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
510 case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
511 return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
513 case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
514 return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
516 case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
517 return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
519 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
520 return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
522 case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
523 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
525 case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
526 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
528 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
529 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
531 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
532 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
534 case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
535 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
537 case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
538 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
540 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
541 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
543 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
544 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
546 case TLS_DH_anon_WITH_RC4_128_MD5:
547 return "TLS_DH_anon_WITH_RC4_128_MD5";
549 case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
550 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
552 case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
553 return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
555 case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
556 return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
558 /* TLS 1.2 with AES GCM (RFC 5288) */
559 case TLS_RSA_WITH_AES_128_GCM_SHA256:
560 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
562 case TLS_RSA_WITH_AES_256_GCM_SHA384:
563 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
565 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
566 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
568 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
569 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
571 case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
572 return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
574 case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
575 return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
577 case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
578 return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
580 case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
581 return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
583 case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
584 return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
586 case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
587 return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
589 case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
590 return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
592 case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
593 return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
595 /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
596 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
597 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
599 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
600 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
602 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
603 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
605 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
606 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
608 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
609 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
611 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
612 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
614 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
615 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
617 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
618 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
620 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
621 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
623 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
624 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
626 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
627 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
629 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
630 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
632 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
633 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
635 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
636 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
638 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
639 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
641 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
642 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
644 case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
645 return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
648 case SSL_RSA_WITH_NULL_MD5:
649 return "TLS_RSA_WITH_NULL_MD5";
651 case SSL_RSA_WITH_NULL_SHA:
652 return "TLS_RSA_WITH_NULL_SHA";
654 case SSL_RSA_WITH_RC4_128_MD5:
655 return "TLS_RSA_WITH_RC4_128_MD5";
657 case SSL_RSA_WITH_RC4_128_SHA:
658 return "TLS_RSA_WITH_RC4_128_SHA";
660 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
661 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
663 case SSL_DH_anon_WITH_RC4_128_MD5:
664 return "TLS_DH_anon_WITH_RC4_128_MD5";
666 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
667 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
669 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
670 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
671 /* TLS PSK (RFC 4279): */
672 case TLS_PSK_WITH_RC4_128_SHA:
673 return "TLS_PSK_WITH_RC4_128_SHA";
675 case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
676 return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
678 case TLS_PSK_WITH_AES_128_CBC_SHA:
679 return "TLS_PSK_WITH_AES_128_CBC_SHA";
681 case TLS_PSK_WITH_AES_256_CBC_SHA:
682 return "TLS_PSK_WITH_AES_256_CBC_SHA";
684 case TLS_DHE_PSK_WITH_RC4_128_SHA:
685 return "TLS_DHE_PSK_WITH_RC4_128_SHA";
687 case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
688 return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
690 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
691 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
693 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
694 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
696 case TLS_RSA_PSK_WITH_RC4_128_SHA:
697 return "TLS_RSA_PSK_WITH_RC4_128_SHA";
699 case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
700 return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
702 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
703 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
705 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
706 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
708 /* More TLS PSK (RFC 4785): */
709 case TLS_PSK_WITH_NULL_SHA:
710 return "TLS_PSK_WITH_NULL_SHA";
712 case TLS_DHE_PSK_WITH_NULL_SHA:
713 return "TLS_DHE_PSK_WITH_NULL_SHA";
715 case TLS_RSA_PSK_WITH_NULL_SHA:
716 return "TLS_RSA_PSK_WITH_NULL_SHA";
718 /* Even more TLS PSK (RFC 5487): */
719 case TLS_PSK_WITH_AES_128_GCM_SHA256:
720 return "TLS_PSK_WITH_AES_128_GCM_SHA256";
722 case TLS_PSK_WITH_AES_256_GCM_SHA384:
723 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
725 case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
726 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
728 case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
729 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
731 case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
732 return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
734 case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
735 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
737 case TLS_PSK_WITH_AES_128_CBC_SHA256:
738 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
740 case TLS_PSK_WITH_AES_256_CBC_SHA384:
741 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
743 case TLS_PSK_WITH_NULL_SHA256:
744 return "TLS_PSK_WITH_NULL_SHA256";
746 case TLS_PSK_WITH_NULL_SHA384:
747 return "TLS_PSK_WITH_NULL_SHA384";
749 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
750 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
752 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
753 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
755 case TLS_DHE_PSK_WITH_NULL_SHA256:
756 return "TLS_DHE_PSK_WITH_NULL_SHA256";
758 case TLS_DHE_PSK_WITH_NULL_SHA384:
759 return "TLS_RSA_PSK_WITH_NULL_SHA384";
761 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
762 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
764 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
765 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
767 case TLS_RSA_PSK_WITH_NULL_SHA256:
768 return "TLS_RSA_PSK_WITH_NULL_SHA256";
770 case TLS_RSA_PSK_WITH_NULL_SHA384:
771 return "TLS_RSA_PSK_WITH_NULL_SHA384";
773 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
775 return "TLS_NULL_WITH_NULL_NULL";
779 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
783 size_t os_version_len;
784 char *os_version_major, *os_version_minor/*, *os_version_point*/;
786 /* Get the Darwin kernel version from the kernel using sysctl(): */
788 mib[1] = KERN_OSRELEASE;
789 if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
791 os_version = malloc(os_version_len*sizeof(char));
794 if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
799 /* Parse the version: */
800 os_version_major = strtok(os_version, ".");
801 os_version_minor = strtok(NULL, ".");
802 /*os_version_point = strtok(NULL, ".");*/
803 *major = atoi(os_version_major);
804 *minor = atoi(os_version_minor);
807 #endif /* CURL_BUILD_MAC */
809 /* Apple provides a myriad of ways of getting information about a certificate
810 into a string. Some aren't available under iOS or newer cats. So here's
811 a unified function for getting a string describing the certificate that
812 ought to work in all cats starting with Leopard. */
813 CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
815 CFStringRef server_cert_summary = CFSTR("(null)");
818 /* iOS: There's only one way to do this. */
819 server_cert_summary = SecCertificateCopySubjectSummary(cert);
821 #if CURL_BUILD_MAC_10_7
822 /* Lion & later: Get the long description if we can. */
823 if(SecCertificateCopyLongDescription != NULL)
824 server_cert_summary =
825 SecCertificateCopyLongDescription(NULL, cert, NULL);
827 #endif /* CURL_BUILD_MAC_10_7 */
828 #if CURL_BUILD_MAC_10_6
829 /* Snow Leopard: Get the certificate summary. */
830 if(SecCertificateCopySubjectSummary != NULL)
831 server_cert_summary = SecCertificateCopySubjectSummary(cert);
833 #endif /* CURL_BUILD_MAC_10_6 */
834 /* Leopard is as far back as we go... */
835 (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
836 #endif /* CURL_BUILD_IOS */
837 return server_cert_summary;
840 #if CURL_SUPPORT_MAC_10_6
841 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
842 deprecation warnings, so let's not compile this unless it's necessary: */
843 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
844 SecIdentityRef *out_c_a_k)
846 OSStatus status = errSecItemNotFound;
847 SecKeychainAttributeList attr_list;
848 SecKeychainAttribute attr;
849 SecKeychainSearchRef search = NULL;
850 SecCertificateRef cert = NULL;
852 /* Set up the attribute list: */
853 attr_list.count = 1L;
854 attr_list.attr = &attr;
856 /* Set up our lone search criterion: */
857 attr.tag = kSecLabelItemAttr;
859 attr.length = (UInt32)strlen(label);
861 /* Start searching: */
862 status = SecKeychainSearchCreateFromAttributes(NULL,
863 kSecCertificateItemClass,
866 if(status == noErr) {
867 status = SecKeychainSearchCopyNext(search,
868 (SecKeychainItemRef *)&cert);
869 if(status == noErr && cert) {
870 /* If we found a certificate, does it have a private key? */
871 status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
880 #endif /* CURL_SUPPORT_MAC_10_6 */
882 static OSStatus CopyIdentityWithLabel(char *label,
883 SecIdentityRef *out_cert_and_key)
885 OSStatus status = errSecItemNotFound;
887 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
888 /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
889 kSecClassIdentity was introduced in Lion. If both exist, let's use them
890 to find the certificate. */
891 if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
894 CFDictionaryRef query_dict;
895 CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
896 kCFStringEncodingUTF8);
898 /* Set up our search criteria and expected results: */
899 values[0] = kSecClassIdentity; /* we want a certificate and a key */
901 values[1] = kCFBooleanTrue; /* we want a reference */
902 keys[1] = kSecReturnRef;
903 values[2] = kSecMatchLimitOne; /* one is enough, thanks */
904 keys[2] = kSecMatchLimit;
905 /* identity searches need a SecPolicyRef in order to work */
906 values[3] = SecPolicyCreateSSL(false, label_cf);
907 keys[3] = kSecMatchPolicy;
908 query_dict = CFDictionaryCreate(NULL, (const void **)keys,
909 (const void **)values, 4L,
910 &kCFCopyStringDictionaryKeyCallBacks,
911 &kCFTypeDictionaryValueCallBacks);
912 CFRelease(values[3]);
915 /* Do we have a match? */
916 status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
917 CFRelease(query_dict);
920 #if CURL_SUPPORT_MAC_10_6
921 /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
922 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
923 #endif /* CURL_SUPPORT_MAC_10_7 */
925 #elif CURL_SUPPORT_MAC_10_6
926 /* For developers building on older cats, we have no choice but to fall back
927 to SecKeychainSearch. */
928 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
929 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
933 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
934 const char *cPassword,
935 SecIdentityRef *out_cert_and_key)
937 OSStatus status = errSecItemNotFound;
938 CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
939 (const UInt8 *)cPath, strlen(cPath), false);
940 CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
941 cPassword, kCFStringEncodingUTF8) : NULL;
942 CFDataRef pkcs_data = NULL;
944 /* We can import P12 files on iOS or OS X 10.7 or later: */
945 /* These constants are documented as having first appeared in 10.6 but they
946 raise linker errors when used on that cat for some reason. */
947 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
948 if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
949 NULL, NULL, &status)) {
950 const void *cKeys[] = {kSecImportExportPassphrase};
951 const void *cValues[] = {password};
952 CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
953 password ? 1L : 0L, NULL, NULL);
954 CFArrayRef items = NULL;
957 status = SecPKCS12Import(pkcs_data, options, &items);
958 if(status == noErr && items && CFArrayGetCount(items)) {
959 CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
960 const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
961 kSecImportItemIdentity);
963 /* Retain the identity; we don't care about any other data... */
964 CFRetain(temp_identity);
965 *out_cert_and_key = (SecIdentityRef)temp_identity;
971 CFRelease(pkcs_data);
973 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
980 /* This code was borrowed from nss.c, with some modifications:
981 * Determine whether the nickname passed in is a filename that needs to
982 * be loaded as a PEM or a regular NSS nickname.
984 * returns 1 for a file
985 * returns 0 for not a file
987 CF_INLINE bool is_file(const char *filename)
994 if(stat(filename, &st) == 0)
995 return S_ISREG(st.st_mode);
999 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
1002 struct SessionHandle *data = conn->data;
1003 curl_socket_t sockfd = conn->sock[sockindex];
1004 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1006 struct in6_addr addr;
1008 struct in_addr addr;
1009 #endif /* ENABLE_IPV6 */
1010 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1011 SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1012 char *ssl_sessionid;
1013 size_t ssl_sessionid_len;
1014 OSStatus err = noErr;
1016 int darwinver_maj = 0, darwinver_min = 0;
1018 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1019 #endif /* CURL_BUILD_MAC */
1021 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1022 if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
1023 if(connssl->ssl_ctx)
1024 CFRelease(connssl->ssl_ctx);
1025 connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1026 if(!connssl->ssl_ctx) {
1027 failf(data, "SSL: couldn't create a context!");
1028 return CURLE_OUT_OF_MEMORY;
1032 /* The old ST API does not exist under iOS, so don't compile it: */
1033 #if CURL_SUPPORT_MAC_10_8
1034 if(connssl->ssl_ctx)
1035 (void)SSLDisposeContext(connssl->ssl_ctx);
1036 err = SSLNewContext(false, &(connssl->ssl_ctx));
1038 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1039 return CURLE_OUT_OF_MEMORY;
1041 #endif /* CURL_SUPPORT_MAC_10_8 */
1044 if(connssl->ssl_ctx)
1045 (void)SSLDisposeContext(connssl->ssl_ctx);
1046 err = SSLNewContext(false, &(connssl->ssl_ctx));
1048 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1049 return CURLE_OUT_OF_MEMORY;
1051 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1052 connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1054 /* check to see if we've been told to use an explicit SSL/TLS version */
1055 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1056 if(SSLSetProtocolVersionMax != NULL) {
1057 switch(data->set.ssl.version) {
1058 case CURL_SSLVERSION_DEFAULT: default:
1059 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1060 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1062 case CURL_SSLVERSION_TLSv1:
1063 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1064 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1066 case CURL_SSLVERSION_TLSv1_0:
1067 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1068 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
1070 case CURL_SSLVERSION_TLSv1_1:
1071 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
1072 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
1074 case CURL_SSLVERSION_TLSv1_2:
1075 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
1076 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1078 case CURL_SSLVERSION_SSLv3:
1079 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1080 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
1082 case CURL_SSLVERSION_SSLv2:
1083 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
1085 failf(data, "Your version of the OS does not support SSLv2");
1086 return CURLE_SSL_CONNECT_ERROR;
1088 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
1092 #if CURL_SUPPORT_MAC_10_8
1093 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1096 switch (data->set.ssl.version) {
1097 case CURL_SSLVERSION_DEFAULT: default:
1098 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1101 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1104 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1107 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1111 case CURL_SSLVERSION_TLSv1:
1112 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1115 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1118 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1122 case CURL_SSLVERSION_TLSv1_0:
1123 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1127 case CURL_SSLVERSION_TLSv1_1:
1128 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1132 case CURL_SSLVERSION_TLSv1_2:
1133 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1137 case CURL_SSLVERSION_SSLv3:
1138 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1142 case CURL_SSLVERSION_SSLv2:
1143 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1147 failf(data, "Your version of the OS does not support SSLv2");
1148 return CURLE_SSL_CONNECT_ERROR;
1152 #endif /* CURL_SUPPORT_MAC_10_8 */
1155 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
1156 switch(data->set.ssl.version) {
1158 case CURL_SSLVERSION_DEFAULT:
1159 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1162 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1166 case CURL_SSLVERSION_TLSv1:
1167 case CURL_SSLVERSION_TLSv1_0:
1168 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1172 case CURL_SSLVERSION_TLSv1_1:
1173 failf(data, "Your version of the OS does not support TLSv1.1");
1174 return CURLE_SSL_CONNECT_ERROR;
1175 case CURL_SSLVERSION_TLSv1_2:
1176 failf(data, "Your version of the OS does not support TLSv1.2");
1177 return CURLE_SSL_CONNECT_ERROR;
1178 case CURL_SSLVERSION_SSLv2:
1179 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1183 failf(data, "Your version of the OS does not support SSLv2");
1184 return CURLE_SSL_CONNECT_ERROR;
1187 case CURL_SSLVERSION_SSLv3:
1188 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1193 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1195 if(data->set.str[STRING_KEY]) {
1196 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1197 "Transport. The private key must be in the Keychain.\n");
1200 if(data->set.str[STRING_CERT]) {
1201 SecIdentityRef cert_and_key = NULL;
1202 bool is_cert_file = is_file(data->set.str[STRING_CERT]);
1204 /* User wants to authenticate with a client cert. Look for it:
1205 If we detect that this is a file on disk, then let's load it.
1206 Otherwise, assume that the user wants to use an identity loaded
1207 from the Keychain. */
1209 if(!data->set.str[STRING_CERT_TYPE])
1210 infof(data, "WARNING: SSL: Certificate type not set, assuming "
1211 "PKCS#12 format.\n");
1212 else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
1213 strlen(data->set.str[STRING_CERT_TYPE])) != 0)
1214 infof(data, "WARNING: SSL: The Security framework only supports "
1215 "loading identities that are in PKCS#12 format.\n");
1217 err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
1218 data->set.str[STRING_KEY_PASSWD], &cert_and_key);
1221 err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
1224 SecCertificateRef cert = NULL;
1225 CFTypeRef certs_c[1];
1228 /* If we found one, print it out: */
1229 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1231 CFStringRef cert_summary = CopyCertSubject(cert);
1232 char cert_summary_c[128];
1235 memset(cert_summary_c, 0, 128);
1236 if(CFStringGetCString(cert_summary,
1239 kCFStringEncodingUTF8)) {
1240 infof(data, "Client certificate: %s\n", cert_summary_c);
1242 CFRelease(cert_summary);
1246 certs_c[0] = cert_and_key;
1247 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1248 &kCFTypeArrayCallBacks);
1249 err = SSLSetCertificate(connssl->ssl_ctx, certs);
1253 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1254 return CURLE_SSL_CERTPROBLEM;
1256 CFRelease(cert_and_key);
1260 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1261 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1262 "and its private key.", data->set.str[STRING_CERT]);
1264 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1265 failf(data, "SSL: Couldn't make sense of the data in the "
1266 "certificate \"%s\" and its private key.",
1267 data->set.str[STRING_CERT]);
1269 case -25260: /* errSecPassphraseRequired */
1270 failf(data, "SSL The certificate \"%s\" requires a password.",
1271 data->set.str[STRING_CERT]);
1273 case errSecItemNotFound:
1274 failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1275 "key in the Keychain.", data->set.str[STRING_CERT]);
1278 failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1279 "key: OSStatus %d", data->set.str[STRING_CERT], err);
1282 return CURLE_SSL_CERTPROBLEM;
1286 /* SSL always tries to verify the peer, this only says whether it should
1287 * fail to connect if the verification fails, or if it should continue
1288 * anyway. In the latter case the result of the verification is checked with
1289 * SSL_get_verify_result() below. */
1290 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1291 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1292 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1293 works, it doesn't work as expected under Snow Leopard or Lion.
1294 So we need to call SSLSetEnableCertVerify() on those older cats in order
1295 to disable certificate validation if the user turned that off.
1296 (SecureTransport will always validate the certificate chain by
1298 /* (Note: Darwin 12.x.x is Mountain Lion.) */
1300 if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
1302 if(SSLSetSessionOption != NULL) {
1303 #endif /* CURL_BUILD_MAC */
1304 bool break_on_auth = !data->set.ssl.verifypeer ||
1305 data->set.str[STRING_SSL_CAFILE];
1306 err = SSLSetSessionOption(connssl->ssl_ctx,
1307 kSSLSessionOptionBreakOnServerAuth,
1310 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1311 return CURLE_SSL_CONNECT_ERROR;
1315 #if CURL_SUPPORT_MAC_10_8
1316 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1317 data->set.ssl.verifypeer?true:false);
1319 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1320 return CURLE_SSL_CONNECT_ERROR;
1322 #endif /* CURL_SUPPORT_MAC_10_8 */
1325 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1326 data->set.ssl.verifypeer?true:false);
1328 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1329 return CURLE_SSL_CONNECT_ERROR;
1331 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1333 if(data->set.str[STRING_SSL_CAFILE]) {
1334 bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
1337 failf(data, "SSL: can't load CA certificate file %s",
1338 data->set.str[STRING_SSL_CAFILE]);
1339 return CURLE_SSL_CACERT_BADFILE;
1341 if(!data->set.ssl.verifypeer) {
1342 failf(data, "SSL: CA certificate set, but certificate verification "
1344 return CURLE_SSL_CONNECT_ERROR;
1348 /* Configure hostname check. SNI is used if available.
1349 * Both hostname check and SNI require SSLSetPeerDomainName().
1350 * Also: the verifyhost setting influences SNI usage */
1351 if(data->set.ssl.verifyhost) {
1352 err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1353 strlen(conn->host.name));
1356 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1360 if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
1362 || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
1365 infof(data, "WARNING: using IP address, SNI is being disabled by "
1370 /* Disable cipher suites that ST supports but are not safe. These ciphers
1371 are unlikely to be used in any case since ST gives other ciphers a much
1372 higher priority, but it's probably better that we not connect at all than
1373 to give the user a false sense of security if the server only supports
1374 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1375 (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1376 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1377 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1378 if(all_ciphers && allowed_ciphers &&
1379 SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1380 &all_ciphers_count) == noErr) {
1381 for(i = 0UL ; i < all_ciphers_count ; i++) {
1383 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1384 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1385 Work around the problem here by disabling those ciphers if we are
1386 running in an affected version of OS X. */
1387 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1388 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1391 #endif /* CURL_BUILD_MAC */
1392 switch(all_ciphers[i]) {
1393 /* Disable NULL ciphersuites: */
1394 case SSL_NULL_WITH_NULL_NULL:
1395 case SSL_RSA_WITH_NULL_MD5:
1396 case SSL_RSA_WITH_NULL_SHA:
1397 case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1398 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1399 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1400 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1401 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1402 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1403 case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1404 case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1405 case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1406 case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1407 case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1408 case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1409 case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1410 case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1411 case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1412 /* Disable anonymous ciphersuites: */
1413 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1414 case SSL_DH_anon_WITH_RC4_128_MD5:
1415 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1416 case SSL_DH_anon_WITH_DES_CBC_SHA:
1417 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1418 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1419 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1420 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1421 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1422 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1423 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1424 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1425 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1426 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1427 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1428 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1429 /* Disable weak key ciphersuites: */
1430 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1431 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1432 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1433 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1434 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1435 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1436 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1437 case SSL_RSA_WITH_DES_CBC_SHA:
1438 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1439 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1440 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1441 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1443 case SSL_RSA_WITH_IDEA_CBC_SHA:
1444 case SSL_RSA_WITH_IDEA_CBC_MD5:
1446 default: /* enable everything else */
1447 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1451 err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1452 allowed_ciphers_count);
1454 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1455 return CURLE_SSL_CONNECT_ERROR;
1459 Curl_safefree(all_ciphers);
1460 Curl_safefree(allowed_ciphers);
1461 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1462 return CURLE_OUT_OF_MEMORY;
1464 Curl_safefree(all_ciphers);
1465 Curl_safefree(allowed_ciphers);
1467 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1468 /* We want to enable 1/n-1 when using a CBC cipher unless the user
1469 specifically doesn't want us doing that: */
1470 if(SSLSetSessionOption != NULL)
1471 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1472 !data->set.ssl_enable_beast);
1473 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1475 /* Check if there's a cached ID we can/should use here! */
1476 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1477 &ssl_sessionid_len)) {
1478 /* we got a session id, use it! */
1479 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1481 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1482 return CURLE_SSL_CONNECT_ERROR;
1484 /* Informational message */
1485 infof(data, "SSL re-using session ID\n");
1487 /* If there isn't one, then let's make one up! This has to be done prior
1488 to starting the handshake. */
1492 ssl_sessionid = malloc(256*sizeof(char));
1493 ssl_sessionid_len = snprintf(ssl_sessionid, 256, "curl:%s:%hu",
1494 conn->host.name, conn->remote_port);
1495 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1497 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1498 return CURLE_SSL_CONNECT_ERROR;
1500 retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1501 if(retcode!= CURLE_OK) {
1502 failf(data, "failed to store ssl session");
1507 err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1509 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1510 return CURLE_SSL_CONNECT_ERROR;
1513 /* pass the raw socket into the SSL layers */
1514 /* We need to store the FD in a constant memory address, because
1515 * SSLSetConnection() will not copy that address. I've found that
1516 * conn->sock[sockindex] may change on its own. */
1517 connssl->ssl_sockfd = sockfd;
1518 err = SSLSetConnection(connssl->ssl_ctx, connssl);
1520 failf(data, "SSL: SSLSetConnection() failed: %d", err);
1521 return CURLE_SSL_CONNECT_ERROR;
1524 connssl->connecting_state = ssl_connect_2;
1528 static int pem_to_der(const char *in, unsigned char **out, size_t *outlen)
1530 char *sep, *start, *end;
1535 /* Jump through the separators in the first line. */
1536 sep = strstr(in, "-----");
1539 sep = strstr(sep + 1, "-----");
1545 /* Find beginning of last line separator. */
1546 end = strstr(start, "-----");
1555 b64 = malloc(len + 1);
1561 /* Create base64 string without linefeeds. */
1562 for(i = 0, j = 0; i < len; i++) {
1563 if(start[i] != '\r' && start[i] != '\n')
1564 b64[j++] = start[i];
1568 err = Curl_base64_decode((const char *)b64, out, outlen);
1578 static int read_cert(const char *file, unsigned char **out, size_t *outlen)
1581 ssize_t n, len = 0, cap = 512;
1583 unsigned char buf[cap], *data, *der;
1596 n = read(fd, buf, sizeof(buf));
1607 if(len + n >= cap) {
1609 data = realloc(data, cap);
1616 memcpy(data + len, buf, n);
1622 * Check if the certificate is in PEM format, and convert it to DER. If this
1623 * fails, we assume the certificate is in DER format.
1625 if(pem_to_der((const char *)data, &der, &derlen) == 0) {
1637 static int sslerr_to_curlerr(struct SessionHandle *data, int err)
1640 case errSSLXCertChainInvalid:
1641 failf(data, "SSL certificate problem: Invalid certificate chain");
1642 return CURLE_SSL_CACERT;
1643 case errSSLUnknownRootCert:
1644 failf(data, "SSL certificate problem: Untrusted root certificate");
1645 return CURLE_SSL_CACERT;
1646 case errSSLNoRootCert:
1647 failf(data, "SSL certificate problem: No root certificate");
1648 return CURLE_SSL_CACERT;
1649 case errSSLCertExpired:
1650 failf(data, "SSL certificate problem: Certificate chain had an "
1651 "expired certificate");
1652 return CURLE_SSL_CACERT;
1654 failf(data, "SSL certificate problem: Couldn't understand the server "
1655 "certificate format");
1656 return CURLE_SSL_CONNECT_ERROR;
1657 case errSSLHostNameMismatch:
1658 failf(data, "SSL certificate peer hostname mismatch");
1659 return CURLE_PEER_FAILED_VERIFICATION;
1661 failf(data, "SSL unexpected certificate error %d", err);
1662 return CURLE_SSL_CACERT;
1666 static int verify_cert(const char *cafile, struct SessionHandle *data,
1669 unsigned char *certbuf;
1671 if(read_cert(cafile, &certbuf, &buflen) < 0) {
1672 failf(data, "SSL: failed to read or invalid CA certificate");
1673 return CURLE_SSL_CACERT;
1676 CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, certbuf, buflen);
1679 failf(data, "SSL: failed to allocate array for CA certificate");
1680 return CURLE_OUT_OF_MEMORY;
1683 SecCertificateRef cacert = SecCertificateCreateWithData(kCFAllocatorDefault,
1685 CFRelease(certdata);
1687 failf(data, "SSL: failed to create SecCertificate from CA certificate");
1688 return CURLE_SSL_CACERT;
1692 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
1694 failf(data, "SSL: error getting certificate chain");
1695 return CURLE_OUT_OF_MEMORY;
1697 else if(ret != noErr) {
1698 return sslerr_to_curlerr(data, ret);
1701 CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
1702 &kCFTypeArrayCallBacks);
1703 CFArrayAppendValue(array, cacert);
1706 ret = SecTrustSetAnchorCertificates(trust, array);
1709 return sslerr_to_curlerr(data, ret);
1712 SecTrustResultType trust_eval = 0;
1713 ret = SecTrustEvaluate(trust, &trust_eval);
1717 return sslerr_to_curlerr(data, ret);
1720 switch (trust_eval) {
1721 case kSecTrustResultUnspecified:
1722 case kSecTrustResultProceed:
1723 infof(data, "SSL: certificate verification succeeded (result: %d)",
1727 case kSecTrustResultRecoverableTrustFailure:
1728 case kSecTrustResultDeny:
1730 failf(data, "SSL: certificate verification failed (result: %d)",
1732 return CURLE_PEER_FAILED_VERIFICATION;
1737 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1739 struct SessionHandle *data = conn->data;
1740 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1742 SSLCipherSuite cipher;
1743 SSLProtocol protocol = 0;
1745 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1746 || ssl_connect_2_reading == connssl->connecting_state
1747 || ssl_connect_2_writing == connssl->connecting_state);
1749 /* Here goes nothing: */
1750 err = SSLHandshake(connssl->ssl_ctx);
1754 case errSSLWouldBlock: /* they're not done with us yet */
1755 connssl->connecting_state = connssl->ssl_direction ?
1756 ssl_connect_2_writing : ssl_connect_2_reading;
1759 /* The below is errSSLServerAuthCompleted; it's not defined in
1760 Leopard's headers */
1762 if(data->set.str[STRING_SSL_CAFILE]) {
1763 int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
1768 /* the documentation says we need to call SSLHandshake() again */
1769 return darwinssl_connect_step2(conn, sockindex);
1771 /* These are all certificate problems with the server: */
1772 case errSSLXCertChainInvalid:
1773 failf(data, "SSL certificate problem: Invalid certificate chain");
1774 return CURLE_SSL_CACERT;
1775 case errSSLUnknownRootCert:
1776 failf(data, "SSL certificate problem: Untrusted root certificate");
1777 return CURLE_SSL_CACERT;
1778 case errSSLNoRootCert:
1779 failf(data, "SSL certificate problem: No root certificate");
1780 return CURLE_SSL_CACERT;
1781 case errSSLCertExpired:
1782 failf(data, "SSL certificate problem: Certificate chain had an "
1783 "expired certificate");
1784 return CURLE_SSL_CACERT;
1786 failf(data, "SSL certificate problem: Couldn't understand the server "
1787 "certificate format");
1788 return CURLE_SSL_CONNECT_ERROR;
1790 /* These are all certificate problems with the client: */
1791 case errSecAuthFailed:
1792 failf(data, "SSL authentication failed");
1793 return CURLE_SSL_CONNECT_ERROR;
1794 case errSSLPeerHandshakeFail:
1795 failf(data, "SSL peer handshake failed, the server most likely "
1796 "requires a client certificate to connect");
1797 return CURLE_SSL_CONNECT_ERROR;
1798 case errSSLPeerUnknownCA:
1799 failf(data, "SSL server rejected the client certificate due to "
1800 "the certificate being signed by an unknown certificate "
1802 return CURLE_SSL_CONNECT_ERROR;
1804 /* This error is raised if the server's cert didn't match the server's
1806 case errSSLHostNameMismatch:
1807 failf(data, "SSL certificate peer verification failed, the "
1808 "certificate did not match \"%s\"\n", conn->host.dispname);
1809 return CURLE_PEER_FAILED_VERIFICATION;
1811 /* Generic handshake errors: */
1812 case errSSLConnectionRefused:
1813 failf(data, "Server dropped the connection during the SSL handshake");
1814 return CURLE_SSL_CONNECT_ERROR;
1815 case errSSLClosedAbort:
1816 failf(data, "Server aborted the SSL handshake");
1817 return CURLE_SSL_CONNECT_ERROR;
1818 case errSSLNegotiation:
1819 failf(data, "Could not negotiate an SSL cipher suite with the server");
1820 return CURLE_SSL_CONNECT_ERROR;
1821 /* Sometimes paramErr happens with buggy ciphers: */
1822 case paramErr: case errSSLInternal:
1823 failf(data, "Internal SSL engine error encountered during the "
1825 return CURLE_SSL_CONNECT_ERROR;
1826 case errSSLFatalAlert:
1827 failf(data, "Fatal SSL engine error encountered during the SSL "
1829 return CURLE_SSL_CONNECT_ERROR;
1831 failf(data, "Unknown SSL protocol error in connection to %s:%d",
1832 conn->host.name, err);
1833 return CURLE_SSL_CONNECT_ERROR;
1837 /* we have been connected fine, we're not waiting for anything else. */
1838 connssl->connecting_state = ssl_connect_3;
1840 /* Informational message */
1841 (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1842 (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1845 infof(data, "SSL 2.0 connection using %s\n",
1846 SSLCipherNameForNumber(cipher));
1849 infof(data, "SSL 3.0 connection using %s\n",
1850 SSLCipherNameForNumber(cipher));
1853 infof(data, "TLS 1.0 connection using %s\n",
1854 TLSCipherNameForNumber(cipher));
1856 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1857 case kTLSProtocol11:
1858 infof(data, "TLS 1.1 connection using %s\n",
1859 TLSCipherNameForNumber(cipher));
1861 case kTLSProtocol12:
1862 infof(data, "TLS 1.2 connection using %s\n",
1863 TLSCipherNameForNumber(cipher));
1867 infof(data, "Unknown protocol connection\n");
1876 darwinssl_connect_step3(struct connectdata *conn,
1879 struct SessionHandle *data = conn->data;
1880 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1881 CFStringRef server_cert_summary;
1882 char server_cert_summary_c[128];
1883 CFArrayRef server_certs = NULL;
1884 SecCertificateRef server_cert;
1887 SecTrustRef trust = NULL;
1889 /* There is no step 3!
1890 * Well, okay, if verbose mode is on, let's print the details of the
1891 * server certificates. */
1892 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1894 #pragma unused(server_certs)
1895 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1896 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1897 a null trust, so be on guard for that: */
1898 if(err == noErr && trust) {
1899 count = SecTrustGetCertificateCount(trust);
1900 for(i = 0L ; i < count ; i++) {
1901 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1902 server_cert_summary = CopyCertSubject(server_cert);
1903 memset(server_cert_summary_c, 0, 128);
1904 if(CFStringGetCString(server_cert_summary,
1905 server_cert_summary_c,
1907 kCFStringEncodingUTF8)) {
1908 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1910 CFRelease(server_cert_summary);
1915 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
1916 The function SecTrustGetCertificateAtIndex() is officially present
1917 in Lion, but it is unfortunately also present in Snow Leopard as
1918 private API and doesn't work as expected. So we have to look for
1919 a different symbol to make sure this code is only executed under
1921 if(SecTrustEvaluateAsync != NULL) {
1922 #pragma unused(server_certs)
1923 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1924 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1925 a null trust, so be on guard for that: */
1926 if(err == noErr && trust) {
1927 count = SecTrustGetCertificateCount(trust);
1928 for(i = 0L ; i < count ; i++) {
1929 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1930 server_cert_summary = CopyCertSubject(server_cert);
1931 memset(server_cert_summary_c, 0, 128);
1932 if(CFStringGetCString(server_cert_summary,
1933 server_cert_summary_c,
1935 kCFStringEncodingUTF8)) {
1936 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1938 CFRelease(server_cert_summary);
1944 #if CURL_SUPPORT_MAC_10_8
1945 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1946 /* Just in case SSLCopyPeerCertificates() returns null too... */
1947 if(err == noErr && server_certs) {
1948 count = CFArrayGetCount(server_certs);
1949 for(i = 0L ; i < count ; i++) {
1950 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
1953 server_cert_summary = CopyCertSubject(server_cert);
1954 memset(server_cert_summary_c, 0, 128);
1955 if(CFStringGetCString(server_cert_summary,
1956 server_cert_summary_c,
1958 kCFStringEncodingUTF8)) {
1959 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1961 CFRelease(server_cert_summary);
1963 CFRelease(server_certs);
1965 #endif /* CURL_SUPPORT_MAC_10_8 */
1967 #endif /* CURL_BUILD_IOS */
1969 #pragma unused(trust)
1970 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1972 count = CFArrayGetCount(server_certs);
1973 for(i = 0L ; i < count ; i++) {
1974 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
1975 server_cert_summary = CopyCertSubject(server_cert);
1976 memset(server_cert_summary_c, 0, 128);
1977 if(CFStringGetCString(server_cert_summary,
1978 server_cert_summary_c,
1980 kCFStringEncodingUTF8)) {
1981 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1983 CFRelease(server_cert_summary);
1985 CFRelease(server_certs);
1987 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1989 connssl->connecting_state = ssl_connect_done;
1993 static Curl_recv darwinssl_recv;
1994 static Curl_send darwinssl_send;
1997 darwinssl_connect_common(struct connectdata *conn,
2003 struct SessionHandle *data = conn->data;
2004 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2005 curl_socket_t sockfd = conn->sock[sockindex];
2009 /* check if the connection has already been established */
2010 if(ssl_connection_complete == connssl->state) {
2015 if(ssl_connect_1==connssl->connecting_state) {
2016 /* Find out how much more time we're allowed */
2017 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2019 if(timeout_ms < 0) {
2020 /* no need to continue if time already is up */
2021 failf(data, "SSL connection timeout");
2022 return CURLE_OPERATION_TIMEDOUT;
2024 retcode = darwinssl_connect_step1(conn, sockindex);
2029 while(ssl_connect_2 == connssl->connecting_state ||
2030 ssl_connect_2_reading == connssl->connecting_state ||
2031 ssl_connect_2_writing == connssl->connecting_state) {
2033 /* check allowed time left */
2034 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2036 if(timeout_ms < 0) {
2037 /* no need to continue if time already is up */
2038 failf(data, "SSL connection timeout");
2039 return CURLE_OPERATION_TIMEDOUT;
2042 /* if ssl is expecting something, check if it's available. */
2043 if(connssl->connecting_state == ssl_connect_2_reading
2044 || connssl->connecting_state == ssl_connect_2_writing) {
2046 curl_socket_t writefd = ssl_connect_2_writing ==
2047 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2048 curl_socket_t readfd = ssl_connect_2_reading ==
2049 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2051 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
2054 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2055 return CURLE_SSL_CONNECT_ERROR;
2057 else if(0 == what) {
2064 failf(data, "SSL connection timeout");
2065 return CURLE_OPERATION_TIMEDOUT;
2068 /* socket is readable or writable */
2071 /* Run transaction, and return to the caller if it failed or if this
2072 * connection is done nonblocking and this loop would execute again. This
2073 * permits the owner of a multi handle to abort a connection attempt
2074 * before step2 has completed while ensuring that a client using select()
2075 * or epoll() will always have a valid fdset to wait on.
2077 retcode = darwinssl_connect_step2(conn, sockindex);
2078 if(retcode || (nonblocking &&
2079 (ssl_connect_2 == connssl->connecting_state ||
2080 ssl_connect_2_reading == connssl->connecting_state ||
2081 ssl_connect_2_writing == connssl->connecting_state)))
2084 } /* repeat step2 until all transactions are done. */
2087 if(ssl_connect_3==connssl->connecting_state) {
2088 retcode = darwinssl_connect_step3(conn, sockindex);
2093 if(ssl_connect_done==connssl->connecting_state) {
2094 connssl->state = ssl_connection_complete;
2095 conn->recv[sockindex] = darwinssl_recv;
2096 conn->send[sockindex] = darwinssl_send;
2102 /* Reset our connect state machine */
2103 connssl->connecting_state = ssl_connect_1;
2109 Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
2113 return darwinssl_connect_common(conn, sockindex, TRUE, done);
2117 Curl_darwinssl_connect(struct connectdata *conn,
2123 retcode = darwinssl_connect_common(conn, sockindex, FALSE, &done);
2133 void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
2135 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2137 if(connssl->ssl_ctx) {
2138 (void)SSLClose(connssl->ssl_ctx);
2139 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2140 if(SSLCreateContext != NULL)
2141 CFRelease(connssl->ssl_ctx);
2142 #if CURL_SUPPORT_MAC_10_8
2144 (void)SSLDisposeContext(connssl->ssl_ctx);
2145 #endif /* CURL_SUPPORT_MAC_10_8 */
2147 (void)SSLDisposeContext(connssl->ssl_ctx);
2148 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2149 connssl->ssl_ctx = NULL;
2151 connssl->ssl_sockfd = 0;
2154 void Curl_darwinssl_close_all(struct SessionHandle *data)
2156 /* SecureTransport doesn't separate sessions from contexts, so... */
2160 int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
2162 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2163 struct SessionHandle *data = conn->data;
2169 if(!connssl->ssl_ctx)
2172 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
2175 Curl_darwinssl_close(conn, sockindex);
2179 what = Curl_socket_ready(conn->sock[sockindex],
2180 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
2184 /* anything that gets here is fatally bad */
2185 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2190 if(!what) { /* timeout */
2191 failf(data, "SSL shutdown timeout");
2195 /* Something to read, let's do it and hope that it is the close
2196 notify alert from the server. No way to SSL_Read now, so use read(). */
2198 nread = read(conn->sock[sockindex], buf, sizeof(buf));
2201 failf(data, "read: %s", strerror(errno));
2208 what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
2214 void Curl_darwinssl_session_free(void *ptr)
2216 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
2217 cached session ID inside the Security framework. There is a private
2218 function that does this, but I don't want to have to explain to you why I
2219 got your application rejected from the App Store due to the use of a
2220 private API, so the best we can do is free up our own char array that we
2221 created way back in darwinssl_connect_step1... */
2225 size_t Curl_darwinssl_version(char *buffer, size_t size)
2227 return snprintf(buffer, size, "SecureTransport");
2231 * This function uses SSLGetSessionState to determine connection status.
2234 * 1 means the connection is still in place
2235 * 0 means the connection has been closed
2236 * -1 means the connection status is unknown
2238 int Curl_darwinssl_check_cxn(struct connectdata *conn)
2240 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2242 SSLSessionState state;
2244 if(connssl->ssl_ctx) {
2245 err = SSLGetSessionState(connssl->ssl_ctx, &state);
2247 return state == kSSLConnected || state == kSSLHandshake;
2253 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2256 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2260 if(connssl->ssl_ctx) { /* SSL is in use */
2261 err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
2263 return buffer > 0UL;
2270 void Curl_darwinssl_random(struct SessionHandle *data,
2271 unsigned char *entropy,
2274 /* arc4random_buf() isn't available on cats older than Lion, so let's
2275 do this manually for the benefit of the older cats. */
2277 u_int32_t random_number = 0;
2279 for(i = 0 ; i < length ; i++) {
2280 if(i % sizeof(u_int32_t) == 0)
2281 random_number = arc4random();
2282 entropy[i] = random_number & 0xFF;
2283 random_number >>= 8;
2285 i = random_number = 0;
2289 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2291 unsigned char *md5sum, /* output */
2295 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2298 static ssize_t darwinssl_send(struct connectdata *conn,
2304 /*struct SessionHandle *data = conn->data;*/
2305 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2306 size_t processed = 0UL;
2309 /* The SSLWrite() function works a little differently than expected. The
2310 fourth argument (processed) is currently documented in Apple's
2311 documentation as: "On return, the length, in bytes, of the data actually
2314 Now, one could interpret that as "written to the socket," but actually,
2315 it returns the amount of data that was written to a buffer internal to
2316 the SSLContextRef instead. So it's possible for SSLWrite() to return
2317 errSSLWouldBlock and a number of bytes "written" because those bytes were
2318 encrypted and written to a buffer, not to the socket.
2320 So if this happens, then we need to keep calling SSLWrite() over and
2321 over again with no new data until it quits returning errSSLWouldBlock. */
2323 /* Do we have buffered data to write from the last time we were called? */
2324 if(connssl->ssl_write_buffered_length) {
2325 /* Write the buffered data: */
2326 err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
2329 /* processed is always going to be 0 because we didn't write to
2330 the buffer, so return how much was written to the socket */
2331 processed = connssl->ssl_write_buffered_length;
2332 connssl->ssl_write_buffered_length = 0UL;
2334 case errSSLWouldBlock: /* argh, try again */
2335 *curlcode = CURLE_AGAIN;
2338 failf(conn->data, "SSLWrite() returned error %d", err);
2339 *curlcode = CURLE_SEND_ERROR;
2344 /* We've got new data to write: */
2345 err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
2348 case errSSLWouldBlock:
2349 /* Data was buffered but not sent, we have to tell the caller
2350 to try sending again, and remember how much was buffered */
2351 connssl->ssl_write_buffered_length = len;
2352 *curlcode = CURLE_AGAIN;
2355 failf(conn->data, "SSLWrite() returned error %d", err);
2356 *curlcode = CURLE_SEND_ERROR;
2361 return (ssize_t)processed;
2364 static ssize_t darwinssl_recv(struct connectdata *conn,
2370 /*struct SessionHandle *data = conn->data;*/
2371 struct ssl_connect_data *connssl = &conn->ssl[num];
2372 size_t processed = 0UL;
2373 OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
2377 case errSSLWouldBlock: /* return how much we read (if anything) */
2379 return (ssize_t)processed;
2380 *curlcode = CURLE_AGAIN;
2384 /* errSSLClosedGraceful - server gracefully shut down the SSL session
2385 errSSLClosedNoNotify - server hung up on us instead of sending a
2386 closure alert notice, read() is returning 0
2387 Either way, inform the caller that the server disconnected. */
2388 case errSSLClosedGraceful:
2389 case errSSLClosedNoNotify:
2390 *curlcode = CURLE_OK;
2395 failf(conn->data, "SSLRead() return error %d", err);
2396 *curlcode = CURLE_RECV_ERROR;
2401 return (ssize_t)processed;
2404 #endif /* USE_DARWINSSL */