1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 2012-2013, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012-2013, Daniel Stenberg, <daniel@haxx.se>, et al.
11 * This software is licensed as described in the file COPYING, which
12 * you should have received as part of this distribution. The terms
13 * are also available at http://curl.haxx.se/docs/copyright.html.
15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 * copies of the Software, and permit persons to whom the Software is
17 * furnished to do so, under the terms of the COPYING file.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ***************************************************************************/
25 * Source file for all iOS and Mac OS X SecureTransport-specific code for the
26 * TLS/SSL layer. No code but sslgen.c should ever call or use these functions.
29 #include "curl_setup.h"
37 #include <Security/Security.h>
38 #include <Security/SecureTransport.h>
39 #include <CoreFoundation/CoreFoundation.h>
40 #include <CommonCrypto/CommonDigest.h>
41 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
42 #include <sys/sysctl.h>
47 #include "inet_pton.h"
51 #include "curl_darwinssl.h"
53 #define _MPRINTF_REPLACE /* use our functions only */
54 #include <curl/mprintf.h>
56 #include "curl_memory.h"
57 /* The last #include file should be: */
60 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
64 /* In Mountain Lion and iOS 5, Apple made some changes to the API. They
65 added TLS 1.1 and 1.2 support, and deprecated and replaced some
66 functions. You need to build against the Mountain Lion or iOS 5 SDK
67 or later to get TLS 1.1 or 1.2 support working in cURL. We'll weak-link
68 to the newer functions and use them if present in the user's OS.
70 Builders: If you want TLS 1.1 and 1.2 but still want to retain support
71 for older cats, don't forget to set the MACOSX_DEPLOYMENT_TARGET
72 environmental variable prior to building cURL. */
74 /* The following two functions were ripped from Apple sample code,
75 * with some modifications: */
76 static OSStatus SocketRead(SSLConnectionRef connection,
77 void *data, /* owned by
80 size_t *dataLength) /* IN/OUT */
82 size_t bytesToGo = *dataLength;
83 size_t initLen = bytesToGo;
84 UInt8 *currData = (UInt8 *)data;
85 /*int sock = *(int *)connection;*/
86 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
87 int sock = connssl->ssl_sockfd;
97 rrtn = read(sock, currData, bytesToGo);
99 /* this is guesswork... */
101 if(rrtn == 0) { /* EOF = server hung up */
102 /* the framework will turn this into errSSLClosedNoNotify */
103 rtn = errSSLClosedGraceful;
105 else /* do the switch */
108 /* connection closed */
109 rtn = errSSLClosedGraceful;
112 rtn = errSSLClosedAbort;
115 rtn = errSSLWouldBlock;
116 connssl->ssl_direction = false;
127 bytesToGo -= bytesRead;
128 currData += bytesRead;
131 /* filled buffer with incoming data, done */
135 *dataLength = initLen - bytesToGo;
140 static OSStatus SocketWrite(SSLConnectionRef connection,
142 size_t *dataLength) /* IN/OUT */
144 size_t bytesSent = 0;
145 /*int sock = *(int *)connection;*/
146 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
147 int sock = connssl->ssl_sockfd;
149 size_t dataLen = *dataLength;
150 const UInt8 *dataPtr = (UInt8 *)data;
158 (char*)dataPtr + bytesSent,
159 dataLen - bytesSent);
160 } while((length > 0) &&
161 ( (bytesSent += length) < dataLen) );
165 if(theErr == EAGAIN) {
166 ortn = errSSLWouldBlock;
167 connssl->ssl_direction = true;
176 *dataLength = bytesSent;
180 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
182 /* SSL version 3.0 */
183 case SSL_RSA_WITH_NULL_MD5:
184 return "SSL_RSA_WITH_NULL_MD5";
186 case SSL_RSA_WITH_NULL_SHA:
187 return "SSL_RSA_WITH_NULL_SHA";
189 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
190 return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
192 case SSL_RSA_WITH_RC4_128_MD5:
193 return "SSL_RSA_WITH_RC4_128_MD5";
195 case SSL_RSA_WITH_RC4_128_SHA:
196 return "SSL_RSA_WITH_RC4_128_SHA";
198 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
199 return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
201 case SSL_RSA_WITH_IDEA_CBC_SHA:
202 return "SSL_RSA_WITH_IDEA_CBC_SHA";
204 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
205 return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
207 case SSL_RSA_WITH_DES_CBC_SHA:
208 return "SSL_RSA_WITH_DES_CBC_SHA";
210 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
211 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
213 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
214 return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
216 case SSL_DH_DSS_WITH_DES_CBC_SHA:
217 return "SSL_DH_DSS_WITH_DES_CBC_SHA";
219 case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
220 return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
222 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
223 return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
225 case SSL_DH_RSA_WITH_DES_CBC_SHA:
226 return "SSL_DH_RSA_WITH_DES_CBC_SHA";
228 case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
229 return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
231 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
232 return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
234 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
235 return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
237 case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
238 return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
240 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
241 return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
243 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
244 return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
246 case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
247 return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
249 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
250 return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
252 case SSL_DH_anon_WITH_RC4_128_MD5:
253 return "SSL_DH_anon_WITH_RC4_128_MD5";
255 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
256 return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
258 case SSL_DH_anon_WITH_DES_CBC_SHA:
259 return "SSL_DH_anon_WITH_DES_CBC_SHA";
261 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
262 return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
264 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
265 return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
267 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
268 return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
270 /* TLS 1.0 with AES (RFC 3268)
271 (Apparently these are used in SSLv3 implementations as well.) */
272 case TLS_RSA_WITH_AES_128_CBC_SHA:
273 return "TLS_RSA_WITH_AES_128_CBC_SHA";
275 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
276 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
278 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
279 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
281 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
282 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
284 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
285 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
287 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
288 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
290 case TLS_RSA_WITH_AES_256_CBC_SHA:
291 return "TLS_RSA_WITH_AES_256_CBC_SHA";
293 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
294 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
296 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
297 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
299 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
300 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
302 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
303 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
305 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
306 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
308 /* SSL version 2.0 */
309 case SSL_RSA_WITH_RC2_CBC_MD5:
310 return "SSL_RSA_WITH_RC2_CBC_MD5";
312 case SSL_RSA_WITH_IDEA_CBC_MD5:
313 return "SSL_RSA_WITH_IDEA_CBC_MD5";
315 case SSL_RSA_WITH_DES_CBC_MD5:
316 return "SSL_RSA_WITH_DES_CBC_MD5";
318 case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
319 return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
322 return "SSL_NULL_WITH_NULL_NULL";
325 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
327 /* TLS 1.0 with AES (RFC 3268) */
328 case TLS_RSA_WITH_AES_128_CBC_SHA:
329 return "TLS_RSA_WITH_AES_128_CBC_SHA";
331 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
332 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
334 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
335 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
337 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
338 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
340 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
341 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
343 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
344 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
346 case TLS_RSA_WITH_AES_256_CBC_SHA:
347 return "TLS_RSA_WITH_AES_256_CBC_SHA";
349 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
350 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
352 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
353 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
355 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
356 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
358 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
359 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
361 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
362 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
364 #if defined(__MAC_10_6) || defined(__IPHONE_5_0)
365 /* TLS 1.0 with ECDSA (RFC 4492) */
366 case TLS_ECDH_ECDSA_WITH_NULL_SHA:
367 return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
369 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
370 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
372 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
373 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
375 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
376 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
378 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
379 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
381 case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
382 return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
384 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
385 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
387 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
388 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
390 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
391 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
393 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
394 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
396 case TLS_ECDH_RSA_WITH_NULL_SHA:
397 return "TLS_ECDH_RSA_WITH_NULL_SHA";
399 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
400 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
402 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
403 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
405 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
406 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
408 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
409 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
411 case TLS_ECDHE_RSA_WITH_NULL_SHA:
412 return "TLS_ECDHE_RSA_WITH_NULL_SHA";
414 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
415 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
417 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
418 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
420 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
421 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
423 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
424 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
426 case TLS_ECDH_anon_WITH_NULL_SHA:
427 return "TLS_ECDH_anon_WITH_NULL_SHA";
429 case TLS_ECDH_anon_WITH_RC4_128_SHA:
430 return "TLS_ECDH_anon_WITH_RC4_128_SHA";
432 case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
433 return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
435 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
436 return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
438 case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
439 return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
441 #endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
442 #if defined(__MAC_10_8) || defined(__IPHONE_5_0)
443 /* TLS 1.2 (RFC 5246) */
444 case TLS_RSA_WITH_NULL_MD5:
445 return "TLS_RSA_WITH_NULL_MD5";
447 case TLS_RSA_WITH_NULL_SHA:
448 return "TLS_RSA_WITH_NULL_SHA";
450 case TLS_RSA_WITH_RC4_128_MD5:
451 return "TLS_RSA_WITH_RC4_128_MD5";
453 case TLS_RSA_WITH_RC4_128_SHA:
454 return "TLS_RSA_WITH_RC4_128_SHA";
456 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
457 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
459 case TLS_RSA_WITH_NULL_SHA256:
460 return "TLS_RSA_WITH_NULL_SHA256";
462 case TLS_RSA_WITH_AES_128_CBC_SHA256:
463 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
465 case TLS_RSA_WITH_AES_256_CBC_SHA256:
466 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
468 case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
469 return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
471 case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
472 return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
474 case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
475 return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
477 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
478 return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
480 case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
481 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
483 case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
484 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
486 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
487 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
489 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
490 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
492 case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
493 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
495 case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
496 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
498 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
499 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
501 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
502 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
504 case TLS_DH_anon_WITH_RC4_128_MD5:
505 return "TLS_DH_anon_WITH_RC4_128_MD5";
507 case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
508 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
510 case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
511 return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
513 case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
514 return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
516 /* TLS 1.2 with AES GCM (RFC 5288) */
517 case TLS_RSA_WITH_AES_128_GCM_SHA256:
518 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
520 case TLS_RSA_WITH_AES_256_GCM_SHA384:
521 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
523 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
524 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
526 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
527 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
529 case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
530 return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
532 case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
533 return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
535 case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
536 return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
538 case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
539 return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
541 case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
542 return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
544 case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
545 return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
547 case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
548 return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
550 case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
551 return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
553 /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
554 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
555 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
557 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
558 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
560 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
561 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
563 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
564 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
566 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
567 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
569 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
570 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
572 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
573 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
575 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
576 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
578 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
579 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
581 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
582 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
584 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
585 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
587 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
588 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
590 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
591 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
593 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
594 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
596 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
597 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
599 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
600 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
602 case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
603 return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
606 case SSL_RSA_WITH_NULL_MD5:
607 return "TLS_RSA_WITH_NULL_MD5";
609 case SSL_RSA_WITH_NULL_SHA:
610 return "TLS_RSA_WITH_NULL_SHA";
612 case SSL_RSA_WITH_RC4_128_MD5:
613 return "TLS_RSA_WITH_RC4_128_MD5";
615 case SSL_RSA_WITH_RC4_128_SHA:
616 return "TLS_RSA_WITH_RC4_128_SHA";
618 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
619 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
621 case SSL_DH_anon_WITH_RC4_128_MD5:
622 return "TLS_DH_anon_WITH_RC4_128_MD5";
624 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
625 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
627 #endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
629 return "TLS_NULL_WITH_NULL_NULL";
632 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
633 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
637 size_t os_version_len;
638 char *os_version_major, *os_version_minor/*, *os_version_point*/;
640 /* Get the Darwin kernel version from the kernel using sysctl(): */
642 mib[1] = KERN_OSRELEASE;
643 if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
645 os_version = malloc(os_version_len*sizeof(char));
648 if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
653 /* Parse the version: */
654 os_version_major = strtok(os_version, ".");
655 os_version_minor = strtok(NULL, ".");
656 /*os_version_point = strtok(NULL, ".");*/
657 *major = atoi(os_version_major);
658 *minor = atoi(os_version_minor);
663 /* Apple provides a myriad of ways of getting information about a certificate
664 into a string. Some aren't available under iOS or newer cats. So here's
665 a unified function for getting a string describing the certificate that
666 ought to work in all cats starting with Leopard. */
667 CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
669 CFStringRef server_cert_summary = CFSTR("(null)");
671 #if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
672 /* iOS: There's only one way to do this. */
673 server_cert_summary = SecCertificateCopySubjectSummary(cert);
675 #if defined(__MAC_10_7)
676 /* Lion & later: Get the long description if we can. */
677 if(SecCertificateCopyLongDescription != NULL)
678 server_cert_summary =
679 SecCertificateCopyLongDescription(NULL, cert, NULL);
681 #endif /* defined(__MAC_10_7) */
682 #if defined(__MAC_10_6)
683 /* Snow Leopard: Get the certificate summary. */
684 if(SecCertificateCopySubjectSummary != NULL)
685 server_cert_summary = SecCertificateCopySubjectSummary(cert);
687 #endif /* defined(__MAC_10_6) */
688 /* Leopard is as far back as we go... */
689 (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
690 #endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
691 return server_cert_summary;
694 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
695 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
696 SecIdentityRef *out_c_a_k)
698 OSStatus status = errSecItemNotFound;
699 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
700 deprecation warnings, so let's not compile this unless it's necessary: */
701 #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
702 SecKeychainAttributeList attr_list;
703 SecKeychainAttribute attr;
704 SecKeychainSearchRef search = NULL;
705 SecCertificateRef cert = NULL;
707 /* Set up the attribute list: */
708 attr_list.count = 1L;
709 attr_list.attr = &attr;
711 /* Set up our lone search criterion: */
712 attr.tag = kSecLabelItemAttr;
714 attr.length = (UInt32)strlen(label);
716 /* Start searching: */
717 status = SecKeychainSearchCreateFromAttributes(NULL,
718 kSecCertificateItemClass,
721 if(status == noErr) {
722 status = SecKeychainSearchCopyNext(search,
723 (SecKeychainItemRef *)&cert);
724 if(status == noErr && cert) {
725 /* If we found a certificate, does it have a private key? */
726 status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
734 #pragma unused(label, out_c_a_k)
735 #endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7 */
738 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
740 static OSStatus CopyIdentityWithLabel(char *label,
741 SecIdentityRef *out_cert_and_key)
743 OSStatus status = errSecItemNotFound;
745 #if defined(__MAC_10_6) || defined(__IPHONE_2_0)
746 /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. If it
747 exists, let's use that to find the certificate. */
748 if(SecItemCopyMatching != NULL) {
751 CFDictionaryRef query_dict;
752 CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
753 kCFStringEncodingUTF8);
755 /* Set up our search criteria and expected results: */
756 values[0] = kSecClassIdentity; /* we want a certificate and a key */
758 values[1] = kCFBooleanTrue; /* we want a reference */
759 keys[1] = kSecReturnRef;
760 values[2] = kSecMatchLimitOne; /* one is enough, thanks */
761 keys[2] = kSecMatchLimit;
762 /* identity searches need a SecPolicyRef in order to work */
763 values[3] = SecPolicyCreateSSL(false, label_cf);
764 keys[3] = kSecMatchPolicy;
765 query_dict = CFDictionaryCreate(NULL, (const void **)keys,
766 (const void **)values, 4L,
767 &kCFCopyStringDictionaryKeyCallBacks,
768 &kCFTypeDictionaryValueCallBacks);
769 CFRelease(values[3]);
772 /* Do we have a match? */
773 status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
774 CFRelease(query_dict);
777 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
778 /* On Leopard, fall back to SecKeychainSearch. */
779 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
780 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
782 #elif (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
783 /* For developers building on Leopard, we have no choice but to fall back. */
784 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
785 #endif /* defined(__MAC_10_6) || defined(__IPHONE_2_0) */
789 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
792 struct SessionHandle *data = conn->data;
793 curl_socket_t sockfd = conn->sock[sockindex];
794 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
796 struct in6_addr addr;
800 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
801 SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
803 size_t ssl_sessionid_len;
804 OSStatus err = noErr;
805 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
806 int darwinver_maj = 0, darwinver_min = 0;
808 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
811 #if defined(__MAC_10_8) || defined(__IPHONE_5_0)
812 if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
814 CFRelease(connssl->ssl_ctx);
815 connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
816 if(!connssl->ssl_ctx) {
817 failf(data, "SSL: couldn't create a context!");
818 return CURLE_OUT_OF_MEMORY;
822 /* The old ST API does not exist under iOS, so don't compile it: */
823 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
825 (void)SSLDisposeContext(connssl->ssl_ctx);
826 err = SSLNewContext(false, &(connssl->ssl_ctx));
828 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
829 return CURLE_OUT_OF_MEMORY;
831 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
835 (void)SSLDisposeContext(connssl->ssl_ctx);
836 err = SSLNewContext(false, &(connssl->ssl_ctx));
838 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
839 return CURLE_OUT_OF_MEMORY;
841 #endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
842 connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
844 /* check to see if we've been told to use an explicit SSL/TLS version */
845 #if defined(__MAC_10_8) || defined(__IPHONE_5_0)
846 if(SSLSetProtocolVersionMax != NULL) {
847 switch(data->set.ssl.version) {
848 case CURL_SSLVERSION_DEFAULT: default:
849 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
850 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
852 case CURL_SSLVERSION_TLSv1:
853 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
854 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
856 case CURL_SSLVERSION_SSLv3:
857 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
858 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
860 case CURL_SSLVERSION_SSLv2:
861 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
862 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
866 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
867 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
870 switch (data->set.ssl.version) {
871 case CURL_SSLVERSION_DEFAULT: default:
872 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
875 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
878 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
881 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
885 case CURL_SSLVERSION_TLSv1:
886 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
889 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
892 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
896 case CURL_SSLVERSION_SSLv3:
897 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
901 case CURL_SSLVERSION_SSLv2:
902 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
907 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
910 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
911 switch(data->set.ssl.version) {
913 case CURL_SSLVERSION_DEFAULT:
914 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
917 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
921 case CURL_SSLVERSION_TLSv1:
922 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
926 case CURL_SSLVERSION_SSLv2:
927 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
931 case CURL_SSLVERSION_SSLv3:
932 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
937 #endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
939 if(data->set.str[STRING_KEY]) {
940 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
941 "Transport. The private key must be in the Keychain.");
944 if(data->set.str[STRING_CERT]) {
945 SecIdentityRef cert_and_key = NULL;
947 /* User wants to authenticate with a client cert. Look for it: */
948 err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
950 SecCertificateRef cert = NULL;
951 CFTypeRef certs_c[1];
954 /* If we found one, print it out: */
955 err = SecIdentityCopyCertificate(cert_and_key, &cert);
957 CFStringRef cert_summary = CopyCertSubject(cert);
958 char cert_summary_c[128];
961 memset(cert_summary_c, 0, 128);
962 if(CFStringGetCString(cert_summary,
965 kCFStringEncodingUTF8)) {
966 infof(data, "Client certificate: %s\n", cert_summary_c);
968 CFRelease(cert_summary);
972 certs_c[0] = cert_and_key;
973 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
974 &kCFTypeArrayCallBacks);
975 err = SSLSetCertificate(connssl->ssl_ctx, certs);
979 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
980 return CURLE_SSL_CERTPROBLEM;
982 CFRelease(cert_and_key);
985 failf(data, "SSL: Can't find the certificate \"%s\" and its private key "
986 "in the Keychain.", data->set.str[STRING_CERT]);
987 return CURLE_SSL_CERTPROBLEM;
991 /* SSL always tries to verify the peer, this only says whether it should
992 * fail to connect if the verification fails, or if it should continue
993 * anyway. In the latter case the result of the verification is checked with
994 * SSL_get_verify_result() below. */
995 #if defined(__MAC_10_6) || defined(__IPHONE_5_0)
996 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
997 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
998 works, it doesn't work as expected under Snow Leopard or Lion.
999 So we need to call SSLSetEnableCertVerify() on those older cats in order
1000 to disable certificate validation if the user turned that off.
1001 (SecureTransport will always validate the certificate chain by
1003 /* (Note: Darwin 12.x.x is Mountain Lion.) */
1004 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1005 if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
1007 if(SSLSetSessionOption != NULL) {
1008 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
1009 err = SSLSetSessionOption(connssl->ssl_ctx,
1010 kSSLSessionOptionBreakOnServerAuth,
1011 data->set.ssl.verifypeer?false:true);
1013 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1014 return CURLE_SSL_CONNECT_ERROR;
1018 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1019 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1020 data->set.ssl.verifypeer?true:false);
1022 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1023 return CURLE_SSL_CONNECT_ERROR;
1025 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
1028 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1029 data->set.ssl.verifypeer?true:false);
1031 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1032 return CURLE_SSL_CONNECT_ERROR;
1034 #endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
1036 /* If this is a domain name and not an IP address, then configure SNI.
1037 * Also: the verifyhost setting influences SNI usage */
1038 /* If this is a domain name and not an IP address, then configure SNI: */
1039 if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
1041 (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
1043 data->set.ssl.verifyhost) {
1044 err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1045 strlen(conn->host.name));
1047 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d",
1052 /* Disable cipher suites that ST supports but are not safe. These ciphers
1053 are unlikely to be used in any case since ST gives other ciphers a much
1054 higher priority, but it's probably better that we not connect at all than
1055 to give the user a false sense of security if the server only supports
1056 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1057 (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1058 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1059 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1060 if(all_ciphers && allowed_ciphers &&
1061 SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1062 &all_ciphers_count) == noErr) {
1063 for(i = 0UL ; i < all_ciphers_count ; i++) {
1064 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1065 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1066 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1067 Work around the problem here by disabling those ciphers if we are
1068 running in an affected version of OS X. */
1069 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1070 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1074 switch(all_ciphers[i]) {
1075 /* Disable NULL ciphersuites: */
1076 case SSL_NULL_WITH_NULL_NULL:
1077 case SSL_RSA_WITH_NULL_MD5:
1078 case SSL_RSA_WITH_NULL_SHA:
1079 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1080 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1081 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1082 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1083 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1084 /* Disable anonymous ciphersuites: */
1085 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1086 case SSL_DH_anon_WITH_RC4_128_MD5:
1087 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1088 case SSL_DH_anon_WITH_DES_CBC_SHA:
1089 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1090 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1091 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1092 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1093 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1094 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1095 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1096 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1097 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1098 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1099 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1100 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1101 /* Disable weak key ciphersuites: */
1102 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1103 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1104 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1105 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1106 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1107 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1108 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1109 case SSL_RSA_WITH_DES_CBC_SHA:
1110 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1111 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1112 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1113 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1115 case SSL_RSA_WITH_IDEA_CBC_SHA:
1116 case SSL_RSA_WITH_IDEA_CBC_MD5:
1118 default: /* enable everything else */
1119 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1123 err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1124 allowed_ciphers_count);
1126 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1127 return CURLE_SSL_CONNECT_ERROR;
1131 Curl_safefree(all_ciphers);
1132 Curl_safefree(allowed_ciphers);
1133 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1134 return CURLE_OUT_OF_MEMORY;
1136 Curl_safefree(all_ciphers);
1137 Curl_safefree(allowed_ciphers);
1139 /* Check if there's a cached ID we can/should use here! */
1140 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1141 &ssl_sessionid_len)) {
1142 /* we got a session id, use it! */
1143 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1145 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1146 return CURLE_SSL_CONNECT_ERROR;
1148 /* Informational message */
1149 infof(data, "SSL re-using session ID\n");
1151 /* If there isn't one, then let's make one up! This has to be done prior
1152 to starting the handshake. */
1156 ssl_sessionid = malloc(256*sizeof(char));
1157 ssl_sessionid_len = snprintf(ssl_sessionid, 256, "curl:%s:%hu",
1158 conn->host.name, conn->remote_port);
1159 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1161 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1162 return CURLE_SSL_CONNECT_ERROR;
1164 retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1165 if(retcode!= CURLE_OK) {
1166 failf(data, "failed to store ssl session");
1171 err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1173 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1174 return CURLE_SSL_CONNECT_ERROR;
1177 /* pass the raw socket into the SSL layers */
1178 /* We need to store the FD in a constant memory address, because
1179 * SSLSetConnection() will not copy that address. I've found that
1180 * conn->sock[sockindex] may change on its own. */
1181 connssl->ssl_sockfd = sockfd;
1182 err = SSLSetConnection(connssl->ssl_ctx, connssl);
1184 failf(data, "SSL: SSLSetConnection() failed: %d", err);
1185 return CURLE_SSL_CONNECT_ERROR;
1188 connssl->connecting_state = ssl_connect_2;
1193 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1195 struct SessionHandle *data = conn->data;
1196 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1198 SSLCipherSuite cipher;
1199 SSLProtocol protocol = 0;
1201 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1202 || ssl_connect_2_reading == connssl->connecting_state
1203 || ssl_connect_2_writing == connssl->connecting_state);
1205 /* Here goes nothing: */
1206 err = SSLHandshake(connssl->ssl_ctx);
1210 case errSSLWouldBlock: /* they're not done with us yet */
1211 connssl->connecting_state = connssl->ssl_direction ?
1212 ssl_connect_2_writing : ssl_connect_2_reading;
1215 /* The below is errSSLServerAuthCompleted; it's not defined in
1216 Leopard's headers */
1218 /* the documentation says we need to call SSLHandshake() again */
1219 return darwinssl_connect_step2(conn, sockindex);
1221 /* These are all certificate problems with the server: */
1222 case errSSLXCertChainInvalid:
1223 failf(data, "SSL certificate problem: Invalid certificate chain");
1224 return CURLE_SSL_CACERT;
1225 case errSSLUnknownRootCert:
1226 failf(data, "SSL certificate problem: Untrusted root certificate");
1227 return CURLE_SSL_CACERT;
1228 case errSSLNoRootCert:
1229 failf(data, "SSL certificate problem: No root certificate");
1230 return CURLE_SSL_CACERT;
1231 case errSSLCertExpired:
1232 failf(data, "SSL certificate problem: Certificate chain had an "
1233 "expired certificate");
1234 return CURLE_SSL_CACERT;
1236 failf(data, "SSL certificate problem: Couldn't understand the server "
1237 "certificate format");
1238 return CURLE_SSL_CONNECT_ERROR;
1240 /* These are all certificate problems with the client: */
1241 case errSecAuthFailed:
1242 failf(data, "SSL authentication failed");
1243 return CURLE_SSL_CONNECT_ERROR;
1244 case errSSLPeerHandshakeFail:
1245 failf(data, "SSL peer handshake failed, the server most likely "
1246 "requires a client certificate to connect");
1247 return CURLE_SSL_CONNECT_ERROR;
1248 case errSSLPeerUnknownCA:
1249 failf(data, "SSL server rejected the client certificate due to "
1250 "the certificate being signed by an unknown certificate "
1252 return CURLE_SSL_CONNECT_ERROR;
1254 /* This error is raised if the server's cert didn't match the server's
1256 case errSSLHostNameMismatch:
1257 failf(data, "SSL certificate peer verification failed, the "
1258 "certificate did not match \"%s\"\n", conn->host.dispname);
1259 return CURLE_PEER_FAILED_VERIFICATION;
1261 /* Generic handshake errors: */
1262 case errSSLConnectionRefused:
1263 failf(data, "Server dropped the connection during the SSL handshake");
1264 return CURLE_SSL_CONNECT_ERROR;
1265 case errSSLClosedAbort:
1266 failf(data, "Server aborted the SSL handshake");
1267 return CURLE_SSL_CONNECT_ERROR;
1268 case errSSLNegotiation:
1269 failf(data, "Could not negotiate an SSL cipher suite with the server");
1270 return CURLE_SSL_CONNECT_ERROR;
1271 /* Sometimes paramErr happens with buggy ciphers: */
1272 case paramErr: case errSSLInternal:
1273 failf(data, "Internal SSL engine error encountered during the "
1275 return CURLE_SSL_CONNECT_ERROR;
1276 case errSSLFatalAlert:
1277 failf(data, "Fatal SSL engine error encountered during the SSL "
1279 return CURLE_SSL_CONNECT_ERROR;
1281 failf(data, "Unknown SSL protocol error in connection to %s:%d",
1282 conn->host.name, err);
1283 return CURLE_SSL_CONNECT_ERROR;
1287 /* we have been connected fine, we're not waiting for anything else. */
1288 connssl->connecting_state = ssl_connect_3;
1290 /* Informational message */
1291 (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1292 (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1295 infof(data, "SSL 2.0 connection using %s\n",
1296 SSLCipherNameForNumber(cipher));
1299 infof(data, "SSL 3.0 connection using %s\n",
1300 SSLCipherNameForNumber(cipher));
1303 infof(data, "TLS 1.0 connection using %s\n",
1304 TLSCipherNameForNumber(cipher));
1306 #if defined(__MAC_10_8) || defined(__IPHONE_5_0)
1307 case kTLSProtocol11:
1308 infof(data, "TLS 1.1 connection using %s\n",
1309 TLSCipherNameForNumber(cipher));
1311 case kTLSProtocol12:
1312 infof(data, "TLS 1.2 connection using %s\n",
1313 TLSCipherNameForNumber(cipher));
1317 infof(data, "Unknown protocol connection\n");
1326 darwinssl_connect_step3(struct connectdata *conn,
1329 struct SessionHandle *data = conn->data;
1330 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1331 CFStringRef server_cert_summary;
1332 char server_cert_summary_c[128];
1333 CFArrayRef server_certs;
1334 SecCertificateRef server_cert;
1339 /* There is no step 3!
1340 * Well, okay, if verbose mode is on, let's print the details of the
1341 * server certificates. */
1342 #if defined(__MAC_10_7) || defined(__IPHONE_5_0)
1343 #if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
1344 #pragma unused(server_certs)
1345 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1347 count = SecTrustGetCertificateCount(trust);
1348 for(i = 0L ; i < count ; i++) {
1349 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1350 server_cert_summary = CopyCertSubject(server_cert);
1351 memset(server_cert_summary_c, 0, 128);
1352 if(CFStringGetCString(server_cert_summary,
1353 server_cert_summary_c,
1355 kCFStringEncodingUTF8)) {
1356 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1358 CFRelease(server_cert_summary);
1363 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
1364 The function SecTrustGetCertificateAtIndex() is officially present
1365 in Lion, but it is unfortunately also present in Snow Leopard as
1366 private API and doesn't work as expected. So we have to look for
1367 a different symbol to make sure this code is only executed under
1369 if(SecTrustEvaluateAsync != NULL) {
1370 #pragma unused(server_certs)
1371 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1373 count = SecTrustGetCertificateCount(trust);
1374 for(i = 0L ; i < count ; i++) {
1375 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1376 server_cert_summary = CopyCertSubject(server_cert);
1377 memset(server_cert_summary_c, 0, 128);
1378 if(CFStringGetCString(server_cert_summary,
1379 server_cert_summary_c,
1381 kCFStringEncodingUTF8)) {
1382 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1384 CFRelease(server_cert_summary);
1390 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1392 count = CFArrayGetCount(server_certs);
1393 for(i = 0L ; i < count ; i++) {
1394 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
1397 server_cert_summary = CopyCertSubject(server_cert);
1398 memset(server_cert_summary_c, 0, 128);
1399 if(CFStringGetCString(server_cert_summary,
1400 server_cert_summary_c,
1402 kCFStringEncodingUTF8)) {
1403 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1405 CFRelease(server_cert_summary);
1407 CFRelease(server_certs);
1410 #endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
1412 #pragma unused(trust)
1413 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1415 count = CFArrayGetCount(server_certs);
1416 for(i = 0L ; i < count ; i++) {
1417 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
1418 server_cert_summary = CopyCertSubject(server_cert);
1419 memset(server_cert_summary_c, 0, 128);
1420 if(CFStringGetCString(server_cert_summary,
1421 server_cert_summary_c,
1423 kCFStringEncodingUTF8)) {
1424 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1426 CFRelease(server_cert_summary);
1428 CFRelease(server_certs);
1430 #endif /* defined(__MAC_10_7) || defined(__IPHONE_5_0) */
1432 connssl->connecting_state = ssl_connect_done;
1436 static Curl_recv darwinssl_recv;
1437 static Curl_send darwinssl_send;
1440 darwinssl_connect_common(struct connectdata *conn,
1446 struct SessionHandle *data = conn->data;
1447 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1448 curl_socket_t sockfd = conn->sock[sockindex];
1452 /* check if the connection has already been established */
1453 if(ssl_connection_complete == connssl->state) {
1458 if(ssl_connect_1==connssl->connecting_state) {
1459 /* Find out how much more time we're allowed */
1460 timeout_ms = Curl_timeleft(data, NULL, TRUE);
1462 if(timeout_ms < 0) {
1463 /* no need to continue if time already is up */
1464 failf(data, "SSL connection timeout");
1465 return CURLE_OPERATION_TIMEDOUT;
1467 retcode = darwinssl_connect_step1(conn, sockindex);
1472 while(ssl_connect_2 == connssl->connecting_state ||
1473 ssl_connect_2_reading == connssl->connecting_state ||
1474 ssl_connect_2_writing == connssl->connecting_state) {
1476 /* check allowed time left */
1477 timeout_ms = Curl_timeleft(data, NULL, TRUE);
1479 if(timeout_ms < 0) {
1480 /* no need to continue if time already is up */
1481 failf(data, "SSL connection timeout");
1482 return CURLE_OPERATION_TIMEDOUT;
1485 /* if ssl is expecting something, check if it's available. */
1486 if(connssl->connecting_state == ssl_connect_2_reading
1487 || connssl->connecting_state == ssl_connect_2_writing) {
1489 curl_socket_t writefd = ssl_connect_2_writing ==
1490 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1491 curl_socket_t readfd = ssl_connect_2_reading ==
1492 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1494 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
1497 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1498 return CURLE_SSL_CONNECT_ERROR;
1500 else if(0 == what) {
1507 failf(data, "SSL connection timeout");
1508 return CURLE_OPERATION_TIMEDOUT;
1511 /* socket is readable or writable */
1514 /* Run transaction, and return to the caller if it failed or if this
1515 * connection is done nonblocking and this loop would execute again. This
1516 * permits the owner of a multi handle to abort a connection attempt
1517 * before step2 has completed while ensuring that a client using select()
1518 * or epoll() will always have a valid fdset to wait on.
1520 retcode = darwinssl_connect_step2(conn, sockindex);
1521 if(retcode || (nonblocking &&
1522 (ssl_connect_2 == connssl->connecting_state ||
1523 ssl_connect_2_reading == connssl->connecting_state ||
1524 ssl_connect_2_writing == connssl->connecting_state)))
1527 } /* repeat step2 until all transactions are done. */
1530 if(ssl_connect_3==connssl->connecting_state) {
1531 retcode = darwinssl_connect_step3(conn, sockindex);
1536 if(ssl_connect_done==connssl->connecting_state) {
1537 connssl->state = ssl_connection_complete;
1538 conn->recv[sockindex] = darwinssl_recv;
1539 conn->send[sockindex] = darwinssl_send;
1545 /* Reset our connect state machine */
1546 connssl->connecting_state = ssl_connect_1;
1552 Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
1556 return darwinssl_connect_common(conn, sockindex, TRUE, done);
1560 Curl_darwinssl_connect(struct connectdata *conn,
1566 retcode = darwinssl_connect_common(conn, sockindex, FALSE, &done);
1576 void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
1578 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1580 if(connssl->ssl_ctx) {
1581 (void)SSLClose(connssl->ssl_ctx);
1582 #if defined(__MAC_10_8) || defined(__IPHONE_5_0)
1583 if(SSLCreateContext != NULL)
1584 CFRelease(connssl->ssl_ctx);
1585 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
1587 (void)SSLDisposeContext(connssl->ssl_ctx);
1588 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
1590 (void)SSLDisposeContext(connssl->ssl_ctx);
1591 #endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
1592 connssl->ssl_ctx = NULL;
1594 connssl->ssl_sockfd = 0;
1597 void Curl_darwinssl_close_all(struct SessionHandle *data)
1599 /* SecureTransport doesn't separate sessions from contexts, so... */
1603 int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
1605 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1606 struct SessionHandle *data = conn->data;
1612 if(!connssl->ssl_ctx)
1615 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
1618 Curl_darwinssl_close(conn, sockindex);
1622 what = Curl_socket_ready(conn->sock[sockindex],
1623 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
1627 /* anything that gets here is fatally bad */
1628 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
1633 if(!what) { /* timeout */
1634 failf(data, "SSL shutdown timeout");
1638 /* Something to read, let's do it and hope that it is the close
1639 notify alert from the server. No way to SSL_Read now, so use read(). */
1641 nread = read(conn->sock[sockindex], buf, sizeof(buf));
1644 failf(data, "read: %s", strerror(errno));
1651 what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
1657 void Curl_darwinssl_session_free(void *ptr)
1659 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
1660 cached session ID inside the Security framework. There is a private
1661 function that does this, but I don't want to have to explain to you why I
1662 got your application rejected from the App Store due to the use of a
1663 private API, so the best we can do is free up our own char array that we
1664 created way back in darwinssl_connect_step1... */
1668 size_t Curl_darwinssl_version(char *buffer, size_t size)
1670 return snprintf(buffer, size, "SecureTransport");
1674 * This function uses SSLGetSessionState to determine connection status.
1677 * 1 means the connection is still in place
1678 * 0 means the connection has been closed
1679 * -1 means the connection status is unknown
1681 int Curl_darwinssl_check_cxn(struct connectdata *conn)
1683 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1685 SSLSessionState state;
1687 if(connssl->ssl_ctx) {
1688 err = SSLGetSessionState(connssl->ssl_ctx, &state);
1690 return state == kSSLConnected || state == kSSLHandshake;
1696 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
1699 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
1703 if(connssl->ssl_ctx) { /* SSL is in use */
1704 err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
1706 return buffer > 0UL;
1713 void Curl_darwinssl_random(struct SessionHandle *data,
1714 unsigned char *entropy,
1717 /* arc4random_buf() isn't available on cats older than Lion, so let's
1718 do this manually for the benefit of the older cats. */
1720 u_int32_t random_number = 0;
1722 for(i = 0 ; i < length ; i++) {
1723 if(i % sizeof(u_int32_t) == 0)
1724 random_number = arc4random();
1725 entropy[i] = random_number & 0xFF;
1726 random_number >>= 8;
1728 i = random_number = 0;
1732 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
1734 unsigned char *md5sum, /* output */
1738 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
1741 static ssize_t darwinssl_send(struct connectdata *conn,
1747 /*struct SessionHandle *data = conn->data;*/
1748 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1749 size_t processed = 0UL;
1752 /* The SSLWrite() function works a little differently than expected. The
1753 fourth argument (processed) is currently documented in Apple's
1754 documentation as: "On return, the length, in bytes, of the data actually
1757 Now, one could interpret that as "written to the socket," but actually,
1758 it returns the amount of data that was written to a buffer internal to
1759 the SSLContextRef instead. So it's possible for SSLWrite() to return
1760 errSSLWouldBlock and a number of bytes "written" because those bytes were
1761 encrypted and written to a buffer, not to the socket.
1763 So if this happens, then we need to keep calling SSLWrite() over and
1764 over again with no new data until it quits returning errSSLWouldBlock. */
1766 /* Do we have buffered data to write from the last time we were called? */
1767 if(connssl->ssl_write_buffered_length) {
1768 /* Write the buffered data: */
1769 err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
1772 /* processed is always going to be 0 because we didn't write to
1773 the buffer, so return how much was written to the socket */
1774 processed = connssl->ssl_write_buffered_length;
1775 connssl->ssl_write_buffered_length = 0UL;
1777 case errSSLWouldBlock: /* argh, try again */
1778 *curlcode = CURLE_AGAIN;
1781 failf(conn->data, "SSLWrite() returned error %d", err);
1782 *curlcode = CURLE_SEND_ERROR;
1787 /* We've got new data to write: */
1788 err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
1791 case errSSLWouldBlock:
1792 /* Data was buffered but not sent, we have to tell the caller
1793 to try sending again, and remember how much was buffered */
1794 connssl->ssl_write_buffered_length = len;
1795 *curlcode = CURLE_AGAIN;
1798 failf(conn->data, "SSLWrite() returned error %d", err);
1799 *curlcode = CURLE_SEND_ERROR;
1804 return (ssize_t)processed;
1807 static ssize_t darwinssl_recv(struct connectdata *conn,
1813 /*struct SessionHandle *data = conn->data;*/
1814 struct ssl_connect_data *connssl = &conn->ssl[num];
1815 size_t processed = 0UL;
1816 OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
1820 case errSSLWouldBlock: /* return how much we read (if anything) */
1822 return (ssize_t)processed;
1823 *curlcode = CURLE_AGAIN;
1827 /* errSSLClosedGraceful - server gracefully shut down the SSL session
1828 errSSLClosedNoNotify - server hung up on us instead of sending a
1829 closure alert notice, read() is returning 0
1830 Either way, inform the caller that the server disconnected. */
1831 case errSSLClosedGraceful:
1832 case errSSLClosedNoNotify:
1833 *curlcode = CURLE_OK;
1838 failf(conn->data, "SSLRead() return error %d", err);
1839 *curlcode = CURLE_RECV_ERROR;
1844 return (ssize_t)processed;
1847 #endif /* USE_DARWINSSL */