libcurl: updated to 7.49.1
[tomato.git] / release / src / router / libcurl / lib / vtls / darwinssl.c
blob71d379b9021ce25b8fe7ecbb9d377e1bdad8d4d6
1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
11 * This software is licensed as described in the file COPYING, which
12 * you should have received as part of this distribution. The terms
13 * are also available at https://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"
33 #include "strtok.h"
35 #ifdef USE_DARWINSSL
37 #ifdef HAVE_LIMITS_H
38 #include <limits.h>
39 #endif
41 #include <Security/Security.h>
42 #include <Security/SecureTransport.h>
43 #include <CoreFoundation/CoreFoundation.h>
44 #include <CommonCrypto/CommonDigest.h>
46 /* The Security framework has changed greatly between iOS and different OS X
47 versions, and we will try to support as many of them as we can (back to
48 Leopard and iOS 5) by using macros and weak-linking.
50 IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
51 you must build this project against the 10.8 SDK or later. */
52 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
54 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
55 #error "The darwinssl back-end requires Leopard or later."
56 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
58 #define CURL_BUILD_IOS 0
59 #define CURL_BUILD_IOS_7 0
60 #define CURL_BUILD_MAC 1
61 /* This is the maximum API level we are allowed to use when building: */
62 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
63 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
64 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
65 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
66 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
67 /* These macros mean "the following code is present to allow runtime backward
68 compatibility with at least this cat or earlier":
69 (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
70 environmental variable.) */
71 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
72 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
73 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
74 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
75 #define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
77 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
78 #define CURL_BUILD_IOS 1
79 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
80 #define CURL_BUILD_MAC 0
81 #define CURL_BUILD_MAC_10_5 0
82 #define CURL_BUILD_MAC_10_6 0
83 #define CURL_BUILD_MAC_10_7 0
84 #define CURL_BUILD_MAC_10_8 0
85 #define CURL_SUPPORT_MAC_10_5 0
86 #define CURL_SUPPORT_MAC_10_6 0
87 #define CURL_SUPPORT_MAC_10_7 0
88 #define CURL_SUPPORT_MAC_10_8 0
89 #define CURL_SUPPORT_MAC_10_9 0
91 #else
92 #error "The darwinssl back-end requires iOS or OS X."
93 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
95 #if CURL_BUILD_MAC
96 #include <sys/sysctl.h>
97 #endif /* CURL_BUILD_MAC */
99 #include "urldata.h"
100 #include "sendf.h"
101 #include "inet_pton.h"
102 #include "connect.h"
103 #include "select.h"
104 #include "vtls.h"
105 #include "darwinssl.h"
106 #include "curl_printf.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: */
113 #define ioErr -36
114 #define paramErr -50
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
120 * caller, data
121 * RETURNED */
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;
131 size_t bytesRead;
132 ssize_t rrtn;
133 int theErr;
135 *dataLength = 0;
137 for(;;) {
138 bytesRead = 0;
139 rrtn = read(sock, currData, bytesToGo);
140 if(rrtn <= 0) {
141 /* this is guesswork... */
142 theErr = errno;
143 if(rrtn == 0) { /* EOF = server hung up */
144 /* the framework will turn this into errSSLClosedNoNotify */
145 rtn = errSSLClosedGraceful;
147 else /* do the switch */
148 switch(theErr) {
149 case ENOENT:
150 /* connection closed */
151 rtn = errSSLClosedGraceful;
152 break;
153 case ECONNRESET:
154 rtn = errSSLClosedAbort;
155 break;
156 case EAGAIN:
157 rtn = errSSLWouldBlock;
158 connssl->ssl_direction = false;
159 break;
160 default:
161 rtn = ioErr;
162 break;
164 break;
166 else {
167 bytesRead = rrtn;
169 bytesToGo -= bytesRead;
170 currData += bytesRead;
172 if(bytesToGo == 0) {
173 /* filled buffer with incoming data, done */
174 break;
177 *dataLength = initLen - bytesToGo;
179 return rtn;
182 static OSStatus SocketWrite(SSLConnectionRef connection,
183 const void *data,
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;
190 ssize_t length;
191 size_t dataLen = *dataLength;
192 const UInt8 *dataPtr = (UInt8 *)data;
193 OSStatus ortn;
194 int theErr;
196 *dataLength = 0;
198 do {
199 length = write(sock,
200 (char*)dataPtr + bytesSent,
201 dataLen - bytesSent);
202 } while((length > 0) &&
203 ( (bytesSent += length) < dataLen) );
205 if(length <= 0) {
206 theErr = errno;
207 if(theErr == EAGAIN) {
208 ortn = errSSLWouldBlock;
209 connssl->ssl_direction = true;
211 else {
212 ortn = ioErr;
215 else {
216 ortn = noErr;
218 *dataLength = bytesSent;
219 return ortn;
222 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
223 switch (cipher) {
224 /* SSL version 3.0 */
225 case SSL_RSA_WITH_NULL_MD5:
226 return "SSL_RSA_WITH_NULL_MD5";
227 break;
228 case SSL_RSA_WITH_NULL_SHA:
229 return "SSL_RSA_WITH_NULL_SHA";
230 break;
231 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
232 return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
233 break;
234 case SSL_RSA_WITH_RC4_128_MD5:
235 return "SSL_RSA_WITH_RC4_128_MD5";
236 break;
237 case SSL_RSA_WITH_RC4_128_SHA:
238 return "SSL_RSA_WITH_RC4_128_SHA";
239 break;
240 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
241 return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
242 break;
243 case SSL_RSA_WITH_IDEA_CBC_SHA:
244 return "SSL_RSA_WITH_IDEA_CBC_SHA";
245 break;
246 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
247 return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
248 break;
249 case SSL_RSA_WITH_DES_CBC_SHA:
250 return "SSL_RSA_WITH_DES_CBC_SHA";
251 break;
252 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
253 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
254 break;
255 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
256 return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
257 break;
258 case SSL_DH_DSS_WITH_DES_CBC_SHA:
259 return "SSL_DH_DSS_WITH_DES_CBC_SHA";
260 break;
261 case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
262 return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
263 break;
264 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
265 return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
266 break;
267 case SSL_DH_RSA_WITH_DES_CBC_SHA:
268 return "SSL_DH_RSA_WITH_DES_CBC_SHA";
269 break;
270 case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
271 return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
272 break;
273 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
274 return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
275 break;
276 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
277 return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
278 break;
279 case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
280 return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
281 break;
282 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
283 return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
284 break;
285 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
286 return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
287 break;
288 case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
289 return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
290 break;
291 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
292 return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
293 break;
294 case SSL_DH_anon_WITH_RC4_128_MD5:
295 return "SSL_DH_anon_WITH_RC4_128_MD5";
296 break;
297 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
298 return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
299 break;
300 case SSL_DH_anon_WITH_DES_CBC_SHA:
301 return "SSL_DH_anon_WITH_DES_CBC_SHA";
302 break;
303 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
304 return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
305 break;
306 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
307 return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
308 break;
309 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
310 return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
311 break;
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";
316 break;
317 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
318 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
319 break;
320 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
321 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
322 break;
323 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
324 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
325 break;
326 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
327 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
328 break;
329 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
330 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
331 break;
332 case TLS_RSA_WITH_AES_256_CBC_SHA:
333 return "TLS_RSA_WITH_AES_256_CBC_SHA";
334 break;
335 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
336 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
337 break;
338 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
339 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
340 break;
341 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
342 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
343 break;
344 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
345 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
346 break;
347 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
348 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
349 break;
350 /* SSL version 2.0 */
351 case SSL_RSA_WITH_RC2_CBC_MD5:
352 return "SSL_RSA_WITH_RC2_CBC_MD5";
353 break;
354 case SSL_RSA_WITH_IDEA_CBC_MD5:
355 return "SSL_RSA_WITH_IDEA_CBC_MD5";
356 break;
357 case SSL_RSA_WITH_DES_CBC_MD5:
358 return "SSL_RSA_WITH_DES_CBC_MD5";
359 break;
360 case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
361 return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
362 break;
364 return "SSL_NULL_WITH_NULL_NULL";
367 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
368 switch(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";
372 break;
373 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
374 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
375 break;
376 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
377 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
378 break;
379 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
380 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
381 break;
382 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
383 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
384 break;
385 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
386 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
387 break;
388 case TLS_RSA_WITH_AES_256_CBC_SHA:
389 return "TLS_RSA_WITH_AES_256_CBC_SHA";
390 break;
391 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
392 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
393 break;
394 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
395 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
396 break;
397 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
398 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
399 break;
400 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
401 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
402 break;
403 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
404 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
405 break;
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";
410 break;
411 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
412 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
413 break;
414 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
415 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
416 break;
417 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
418 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
419 break;
420 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
421 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
422 break;
423 case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
424 return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
425 break;
426 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
427 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
428 break;
429 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
430 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
431 break;
432 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
433 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
434 break;
435 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
436 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
437 break;
438 case TLS_ECDH_RSA_WITH_NULL_SHA:
439 return "TLS_ECDH_RSA_WITH_NULL_SHA";
440 break;
441 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
442 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
443 break;
444 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
445 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
446 break;
447 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
448 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
449 break;
450 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
451 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
452 break;
453 case TLS_ECDHE_RSA_WITH_NULL_SHA:
454 return "TLS_ECDHE_RSA_WITH_NULL_SHA";
455 break;
456 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
457 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
458 break;
459 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
460 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
461 break;
462 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
463 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
464 break;
465 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
466 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
467 break;
468 case TLS_ECDH_anon_WITH_NULL_SHA:
469 return "TLS_ECDH_anon_WITH_NULL_SHA";
470 break;
471 case TLS_ECDH_anon_WITH_RC4_128_SHA:
472 return "TLS_ECDH_anon_WITH_RC4_128_SHA";
473 break;
474 case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
475 return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
476 break;
477 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
478 return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
479 break;
480 case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
481 return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
482 break;
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";
488 break;
489 case TLS_RSA_WITH_NULL_SHA:
490 return "TLS_RSA_WITH_NULL_SHA";
491 break;
492 case TLS_RSA_WITH_RC4_128_MD5:
493 return "TLS_RSA_WITH_RC4_128_MD5";
494 break;
495 case TLS_RSA_WITH_RC4_128_SHA:
496 return "TLS_RSA_WITH_RC4_128_SHA";
497 break;
498 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
499 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
500 break;
501 case TLS_RSA_WITH_NULL_SHA256:
502 return "TLS_RSA_WITH_NULL_SHA256";
503 break;
504 case TLS_RSA_WITH_AES_128_CBC_SHA256:
505 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
506 break;
507 case TLS_RSA_WITH_AES_256_CBC_SHA256:
508 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
509 break;
510 case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
511 return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
512 break;
513 case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
514 return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
515 break;
516 case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
517 return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
518 break;
519 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
520 return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
521 break;
522 case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
523 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
524 break;
525 case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
526 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
527 break;
528 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
529 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
530 break;
531 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
532 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
533 break;
534 case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
535 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
536 break;
537 case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
538 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
539 break;
540 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
541 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
542 break;
543 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
544 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
545 break;
546 case TLS_DH_anon_WITH_RC4_128_MD5:
547 return "TLS_DH_anon_WITH_RC4_128_MD5";
548 break;
549 case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
550 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
551 break;
552 case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
553 return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
554 break;
555 case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
556 return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
557 break;
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";
561 break;
562 case TLS_RSA_WITH_AES_256_GCM_SHA384:
563 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
564 break;
565 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
566 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
567 break;
568 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
569 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
570 break;
571 case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
572 return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
573 break;
574 case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
575 return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
576 break;
577 case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
578 return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
579 break;
580 case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
581 return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
582 break;
583 case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
584 return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
585 break;
586 case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
587 return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
588 break;
589 case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
590 return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
591 break;
592 case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
593 return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
594 break;
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";
598 break;
599 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
600 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
601 break;
602 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
603 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
604 break;
605 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
606 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
607 break;
608 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
609 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
610 break;
611 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
612 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
613 break;
614 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
615 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
616 break;
617 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
618 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
619 break;
620 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
621 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
622 break;
623 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
624 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
625 break;
626 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
627 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
628 break;
629 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
630 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
631 break;
632 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
633 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
634 break;
635 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
636 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
637 break;
638 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
639 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
640 break;
641 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
642 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
643 break;
644 case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
645 return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
646 break;
647 #else
648 case SSL_RSA_WITH_NULL_MD5:
649 return "TLS_RSA_WITH_NULL_MD5";
650 break;
651 case SSL_RSA_WITH_NULL_SHA:
652 return "TLS_RSA_WITH_NULL_SHA";
653 break;
654 case SSL_RSA_WITH_RC4_128_MD5:
655 return "TLS_RSA_WITH_RC4_128_MD5";
656 break;
657 case SSL_RSA_WITH_RC4_128_SHA:
658 return "TLS_RSA_WITH_RC4_128_SHA";
659 break;
660 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
661 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
662 break;
663 case SSL_DH_anon_WITH_RC4_128_MD5:
664 return "TLS_DH_anon_WITH_RC4_128_MD5";
665 break;
666 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
667 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
668 break;
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";
674 break;
675 case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
676 return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
677 break;
678 case TLS_PSK_WITH_AES_128_CBC_SHA:
679 return "TLS_PSK_WITH_AES_128_CBC_SHA";
680 break;
681 case TLS_PSK_WITH_AES_256_CBC_SHA:
682 return "TLS_PSK_WITH_AES_256_CBC_SHA";
683 break;
684 case TLS_DHE_PSK_WITH_RC4_128_SHA:
685 return "TLS_DHE_PSK_WITH_RC4_128_SHA";
686 break;
687 case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
688 return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
689 break;
690 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
691 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
692 break;
693 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
694 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
695 break;
696 case TLS_RSA_PSK_WITH_RC4_128_SHA:
697 return "TLS_RSA_PSK_WITH_RC4_128_SHA";
698 break;
699 case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
700 return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
701 break;
702 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
703 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
704 break;
705 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
706 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
707 break;
708 /* More TLS PSK (RFC 4785): */
709 case TLS_PSK_WITH_NULL_SHA:
710 return "TLS_PSK_WITH_NULL_SHA";
711 break;
712 case TLS_DHE_PSK_WITH_NULL_SHA:
713 return "TLS_DHE_PSK_WITH_NULL_SHA";
714 break;
715 case TLS_RSA_PSK_WITH_NULL_SHA:
716 return "TLS_RSA_PSK_WITH_NULL_SHA";
717 break;
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";
721 break;
722 case TLS_PSK_WITH_AES_256_GCM_SHA384:
723 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
724 break;
725 case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
726 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
727 break;
728 case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
729 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
730 break;
731 case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
732 return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
733 break;
734 case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
735 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
736 break;
737 case TLS_PSK_WITH_AES_128_CBC_SHA256:
738 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
739 break;
740 case TLS_PSK_WITH_AES_256_CBC_SHA384:
741 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
742 break;
743 case TLS_PSK_WITH_NULL_SHA256:
744 return "TLS_PSK_WITH_NULL_SHA256";
745 break;
746 case TLS_PSK_WITH_NULL_SHA384:
747 return "TLS_PSK_WITH_NULL_SHA384";
748 break;
749 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
750 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
751 break;
752 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
753 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
754 break;
755 case TLS_DHE_PSK_WITH_NULL_SHA256:
756 return "TLS_DHE_PSK_WITH_NULL_SHA256";
757 break;
758 case TLS_DHE_PSK_WITH_NULL_SHA384:
759 return "TLS_RSA_PSK_WITH_NULL_SHA384";
760 break;
761 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
762 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
763 break;
764 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
765 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
766 break;
767 case TLS_RSA_PSK_WITH_NULL_SHA256:
768 return "TLS_RSA_PSK_WITH_NULL_SHA256";
769 break;
770 case TLS_RSA_PSK_WITH_NULL_SHA384:
771 return "TLS_RSA_PSK_WITH_NULL_SHA384";
772 break;
773 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
775 return "TLS_NULL_WITH_NULL_NULL";
778 #if CURL_BUILD_MAC
779 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
781 int mib[2];
782 char *os_version;
783 size_t os_version_len;
784 char *os_version_major, *os_version_minor;
785 char *tok_buf;
787 /* Get the Darwin kernel version from the kernel using sysctl(): */
788 mib[0] = CTL_KERN;
789 mib[1] = KERN_OSRELEASE;
790 if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
791 return;
792 os_version = malloc(os_version_len*sizeof(char));
793 if(!os_version)
794 return;
795 if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
796 free(os_version);
797 return;
800 /* Parse the version: */
801 os_version_major = strtok_r(os_version, ".", &tok_buf);
802 os_version_minor = strtok_r(NULL, ".", &tok_buf);
803 *major = atoi(os_version_major);
804 *minor = atoi(os_version_minor);
805 free(os_version);
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)");
817 #if CURL_BUILD_IOS
818 /* iOS: There's only one way to do this. */
819 server_cert_summary = SecCertificateCopySubjectSummary(cert);
820 #else
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);
826 else
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);
832 else
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;
858 attr.data = label;
859 attr.length = (UInt32)strlen(label);
861 /* Start searching: */
862 status = SecKeychainSearchCreateFromAttributes(NULL,
863 kSecCertificateItemClass,
864 &attr_list,
865 &search);
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);
872 CFRelease(cert);
876 if(search)
877 CFRelease(search);
878 return status;
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) {
892 CFTypeRef keys[4];
893 CFTypeRef values[4];
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 */
900 keys[0] = kSecClass;
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]);
913 CFRelease(label_cf);
915 /* Do we have a match? */
916 status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
917 CFRelease(query_dict);
919 else {
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 */
930 return status;
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;
956 /* Here we go: */
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;
968 if(items)
969 CFRelease(items);
970 CFRelease(options);
971 CFRelease(pkcs_data);
973 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
974 if(password)
975 CFRelease(password);
976 CFRelease(pkcs_url);
977 return status;
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)
989 struct_stat st;
991 if(filename == NULL)
992 return false;
994 if(stat(filename, &st) == 0)
995 return S_ISREG(st.st_mode);
996 return false;
999 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
1000 int sockindex)
1002 struct SessionHandle *data = conn->data;
1003 curl_socket_t sockfd = conn->sock[sockindex];
1004 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1005 #ifdef ENABLE_IPV6
1006 struct in6_addr addr;
1007 #else
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;
1015 #if CURL_BUILD_MAC
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;
1031 else {
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));
1037 if(err != noErr) {
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 */
1043 #else
1044 if(connssl->ssl_ctx)
1045 (void)SSLDisposeContext(connssl->ssl_ctx);
1046 err = SSLNewContext(false, &(connssl->ssl_ctx));
1047 if(err != noErr) {
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 default:
1059 case CURL_SSLVERSION_DEFAULT:
1060 case CURL_SSLVERSION_TLSv1:
1061 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1062 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1063 break;
1064 case CURL_SSLVERSION_TLSv1_0:
1065 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1066 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
1067 break;
1068 case CURL_SSLVERSION_TLSv1_1:
1069 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
1070 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
1071 break;
1072 case CURL_SSLVERSION_TLSv1_2:
1073 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
1074 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1075 break;
1076 case CURL_SSLVERSION_SSLv3:
1077 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1078 if(err != noErr) {
1079 failf(data, "Your version of the OS does not support SSLv3");
1080 return CURLE_SSL_CONNECT_ERROR;
1082 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
1083 break;
1084 case CURL_SSLVERSION_SSLv2:
1085 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
1086 if(err != noErr) {
1087 failf(data, "Your version of the OS does not support SSLv2");
1088 return CURLE_SSL_CONNECT_ERROR;
1090 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
1093 else {
1094 #if CURL_SUPPORT_MAC_10_8
1095 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1096 kSSLProtocolAll,
1097 false);
1098 switch (data->set.ssl.version) {
1099 default:
1100 case CURL_SSLVERSION_DEFAULT:
1101 case CURL_SSLVERSION_TLSv1:
1102 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1103 kTLSProtocol1,
1104 true);
1105 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1106 kTLSProtocol11,
1107 true);
1108 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1109 kTLSProtocol12,
1110 true);
1111 break;
1112 case CURL_SSLVERSION_TLSv1_0:
1113 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1114 kTLSProtocol1,
1115 true);
1116 break;
1117 case CURL_SSLVERSION_TLSv1_1:
1118 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1119 kTLSProtocol11,
1120 true);
1121 break;
1122 case CURL_SSLVERSION_TLSv1_2:
1123 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1124 kTLSProtocol12,
1125 true);
1126 break;
1127 case CURL_SSLVERSION_SSLv3:
1128 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1129 kSSLProtocol3,
1130 true);
1131 if(err != noErr) {
1132 failf(data, "Your version of the OS does not support SSLv3");
1133 return CURLE_SSL_CONNECT_ERROR;
1135 break;
1136 case CURL_SSLVERSION_SSLv2:
1137 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1138 kSSLProtocol2,
1139 true);
1140 if(err != noErr) {
1141 failf(data, "Your version of the OS does not support SSLv2");
1142 return CURLE_SSL_CONNECT_ERROR;
1144 break;
1146 #endif /* CURL_SUPPORT_MAC_10_8 */
1148 #else
1149 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
1150 switch(data->set.ssl.version) {
1151 default:
1152 case CURL_SSLVERSION_DEFAULT:
1153 case CURL_SSLVERSION_TLSv1:
1154 case CURL_SSLVERSION_TLSv1_0:
1155 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1156 kTLSProtocol1,
1157 true);
1158 break;
1159 case CURL_SSLVERSION_TLSv1_1:
1160 failf(data, "Your version of the OS does not support TLSv1.1");
1161 return CURLE_SSL_CONNECT_ERROR;
1162 case CURL_SSLVERSION_TLSv1_2:
1163 failf(data, "Your version of the OS does not support TLSv1.2");
1164 return CURLE_SSL_CONNECT_ERROR;
1165 case CURL_SSLVERSION_SSLv2:
1166 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1167 kSSLProtocol2,
1168 true);
1169 if(err != noErr) {
1170 failf(data, "Your version of the OS does not support SSLv2");
1171 return CURLE_SSL_CONNECT_ERROR;
1173 break;
1174 case CURL_SSLVERSION_SSLv3:
1175 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1176 kSSLProtocol3,
1177 true);
1178 if(err != noErr) {
1179 failf(data, "Your version of the OS does not support SSLv3");
1180 return CURLE_SSL_CONNECT_ERROR;
1182 break;
1184 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1186 if(data->set.str[STRING_KEY]) {
1187 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1188 "Transport. The private key must be in the Keychain.\n");
1191 if(data->set.str[STRING_CERT]) {
1192 SecIdentityRef cert_and_key = NULL;
1193 bool is_cert_file = is_file(data->set.str[STRING_CERT]);
1195 /* User wants to authenticate with a client cert. Look for it:
1196 If we detect that this is a file on disk, then let's load it.
1197 Otherwise, assume that the user wants to use an identity loaded
1198 from the Keychain. */
1199 if(is_cert_file) {
1200 if(!data->set.str[STRING_CERT_TYPE])
1201 infof(data, "WARNING: SSL: Certificate type not set, assuming "
1202 "PKCS#12 format.\n");
1203 else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
1204 strlen(data->set.str[STRING_CERT_TYPE])) != 0)
1205 infof(data, "WARNING: SSL: The Security framework only supports "
1206 "loading identities that are in PKCS#12 format.\n");
1208 err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
1209 data->set.str[STRING_KEY_PASSWD], &cert_and_key);
1211 else
1212 err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
1214 if(err == noErr) {
1215 SecCertificateRef cert = NULL;
1216 CFTypeRef certs_c[1];
1217 CFArrayRef certs;
1219 /* If we found one, print it out: */
1220 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1221 if(err == noErr) {
1222 CFStringRef cert_summary = CopyCertSubject(cert);
1223 char cert_summary_c[128];
1225 if(cert_summary) {
1226 memset(cert_summary_c, 0, 128);
1227 if(CFStringGetCString(cert_summary,
1228 cert_summary_c,
1229 128,
1230 kCFStringEncodingUTF8)) {
1231 infof(data, "Client certificate: %s\n", cert_summary_c);
1233 CFRelease(cert_summary);
1234 CFRelease(cert);
1237 certs_c[0] = cert_and_key;
1238 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1239 &kCFTypeArrayCallBacks);
1240 err = SSLSetCertificate(connssl->ssl_ctx, certs);
1241 if(certs)
1242 CFRelease(certs);
1243 if(err != noErr) {
1244 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1245 return CURLE_SSL_CERTPROBLEM;
1247 CFRelease(cert_and_key);
1249 else {
1250 switch(err) {
1251 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1252 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1253 "and its private key.", data->set.str[STRING_CERT]);
1254 break;
1255 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1256 failf(data, "SSL: Couldn't make sense of the data in the "
1257 "certificate \"%s\" and its private key.",
1258 data->set.str[STRING_CERT]);
1259 break;
1260 case -25260: /* errSecPassphraseRequired */
1261 failf(data, "SSL The certificate \"%s\" requires a password.",
1262 data->set.str[STRING_CERT]);
1263 break;
1264 case errSecItemNotFound:
1265 failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1266 "key in the Keychain.", data->set.str[STRING_CERT]);
1267 break;
1268 default:
1269 failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1270 "key: OSStatus %d", data->set.str[STRING_CERT], err);
1271 break;
1273 return CURLE_SSL_CERTPROBLEM;
1277 /* SSL always tries to verify the peer, this only says whether it should
1278 * fail to connect if the verification fails, or if it should continue
1279 * anyway. In the latter case the result of the verification is checked with
1280 * SSL_get_verify_result() below. */
1281 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1282 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1283 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1284 works, it doesn't work as expected under Snow Leopard, Lion or
1285 Mountain Lion.
1286 So we need to call SSLSetEnableCertVerify() on those older cats in order
1287 to disable certificate validation if the user turned that off.
1288 (SecureTransport will always validate the certificate chain by
1289 default.)
1290 Note:
1291 Darwin 11.x.x is Lion (10.7)
1292 Darwin 12.x.x is Mountain Lion (10.8)
1293 Darwin 13.x.x is Mavericks (10.9)
1294 Darwin 14.x.x is Yosemite (10.10)
1295 Darwin 15.x.x is El Capitan (10.11)
1297 #if CURL_BUILD_MAC
1298 if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
1299 #else
1300 if(SSLSetSessionOption != NULL) {
1301 #endif /* CURL_BUILD_MAC */
1302 bool break_on_auth = !data->set.ssl.verifypeer ||
1303 data->set.str[STRING_SSL_CAFILE];
1304 err = SSLSetSessionOption(connssl->ssl_ctx,
1305 kSSLSessionOptionBreakOnServerAuth,
1306 break_on_auth);
1307 if(err != noErr) {
1308 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1309 return CURLE_SSL_CONNECT_ERROR;
1312 else {
1313 #if CURL_SUPPORT_MAC_10_8
1314 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1315 data->set.ssl.verifypeer?true:false);
1316 if(err != noErr) {
1317 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1318 return CURLE_SSL_CONNECT_ERROR;
1320 #endif /* CURL_SUPPORT_MAC_10_8 */
1322 #else
1323 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1324 data->set.ssl.verifypeer?true:false);
1325 if(err != noErr) {
1326 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1327 return CURLE_SSL_CONNECT_ERROR;
1329 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1331 if(data->set.str[STRING_SSL_CAFILE]) {
1332 bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
1334 if(!is_cert_file) {
1335 failf(data, "SSL: can't load CA certificate file %s",
1336 data->set.str[STRING_SSL_CAFILE]);
1337 return CURLE_SSL_CACERT_BADFILE;
1339 if(!data->set.ssl.verifypeer) {
1340 failf(data, "SSL: CA certificate set, but certificate verification "
1341 "is disabled");
1342 return CURLE_SSL_CONNECT_ERROR;
1346 /* Configure hostname check. SNI is used if available.
1347 * Both hostname check and SNI require SSLSetPeerDomainName().
1348 * Also: the verifyhost setting influences SNI usage */
1349 if(data->set.ssl.verifyhost) {
1350 err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1351 strlen(conn->host.name));
1353 if(err != noErr) {
1354 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1355 err);
1358 if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
1359 #ifdef ENABLE_IPV6
1360 || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
1361 #endif
1363 infof(data, "WARNING: using IP address, SNI is being disabled by "
1364 "the OS.\n");
1368 /* Disable cipher suites that ST supports but are not safe. These ciphers
1369 are unlikely to be used in any case since ST gives other ciphers a much
1370 higher priority, but it's probably better that we not connect at all than
1371 to give the user a false sense of security if the server only supports
1372 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1373 (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1374 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1375 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1376 if(all_ciphers && allowed_ciphers &&
1377 SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1378 &all_ciphers_count) == noErr) {
1379 for(i = 0UL ; i < all_ciphers_count ; i++) {
1380 #if CURL_BUILD_MAC
1381 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1382 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1383 Work around the problem here by disabling those ciphers if we are
1384 running in an affected version of OS X. */
1385 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1386 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1387 continue;
1389 #endif /* CURL_BUILD_MAC */
1390 switch(all_ciphers[i]) {
1391 /* Disable NULL ciphersuites: */
1392 case SSL_NULL_WITH_NULL_NULL:
1393 case SSL_RSA_WITH_NULL_MD5:
1394 case SSL_RSA_WITH_NULL_SHA:
1395 case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1396 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1397 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1398 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1399 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1400 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1401 case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1402 case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1403 case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1404 case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1405 case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1406 case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1407 case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1408 case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1409 case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1410 /* Disable anonymous ciphersuites: */
1411 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1412 case SSL_DH_anon_WITH_RC4_128_MD5:
1413 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1414 case SSL_DH_anon_WITH_DES_CBC_SHA:
1415 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1416 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1417 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1418 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1419 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1420 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1421 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1422 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1423 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1424 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1425 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1426 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1427 /* Disable weak key ciphersuites: */
1428 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1429 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1430 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1431 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1432 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1433 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1434 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1435 case SSL_RSA_WITH_DES_CBC_SHA:
1436 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1437 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1438 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1439 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1440 /* Disable IDEA: */
1441 case SSL_RSA_WITH_IDEA_CBC_SHA:
1442 case SSL_RSA_WITH_IDEA_CBC_MD5:
1443 break;
1444 default: /* enable everything else */
1445 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1446 break;
1449 err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1450 allowed_ciphers_count);
1451 if(err != noErr) {
1452 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1453 return CURLE_SSL_CONNECT_ERROR;
1456 else {
1457 Curl_safefree(all_ciphers);
1458 Curl_safefree(allowed_ciphers);
1459 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1460 return CURLE_OUT_OF_MEMORY;
1462 Curl_safefree(all_ciphers);
1463 Curl_safefree(allowed_ciphers);
1465 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1466 /* We want to enable 1/n-1 when using a CBC cipher unless the user
1467 specifically doesn't want us doing that: */
1468 if(SSLSetSessionOption != NULL) {
1469 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1470 !data->set.ssl_enable_beast);
1471 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
1472 data->set.ssl.falsestart); /* false start support */
1474 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1476 /* Check if there's a cached ID we can/should use here! */
1477 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1478 &ssl_sessionid_len)) {
1479 /* we got a session id, use it! */
1480 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1481 if(err != noErr) {
1482 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1483 return CURLE_SSL_CONNECT_ERROR;
1485 /* Informational message */
1486 infof(data, "SSL re-using session ID\n");
1488 /* If there isn't one, then let's make one up! This has to be done prior
1489 to starting the handshake. */
1490 else {
1491 CURLcode result;
1492 ssl_sessionid =
1493 aprintf("%s:%d:%d:%s:%hu", data->set.str[STRING_SSL_CAFILE],
1494 data->set.ssl.verifypeer, data->set.ssl.verifyhost,
1495 conn->host.name, conn->remote_port);
1496 ssl_sessionid_len = strlen(ssl_sessionid);
1498 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1499 if(err != noErr) {
1500 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1501 return CURLE_SSL_CONNECT_ERROR;
1504 result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1505 if(result) {
1506 failf(data, "failed to store ssl session");
1507 return result;
1511 err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1512 if(err != noErr) {
1513 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1514 return CURLE_SSL_CONNECT_ERROR;
1517 /* pass the raw socket into the SSL layers */
1518 /* We need to store the FD in a constant memory address, because
1519 * SSLSetConnection() will not copy that address. I've found that
1520 * conn->sock[sockindex] may change on its own. */
1521 connssl->ssl_sockfd = sockfd;
1522 err = SSLSetConnection(connssl->ssl_ctx, connssl);
1523 if(err != noErr) {
1524 failf(data, "SSL: SSLSetConnection() failed: %d", err);
1525 return CURLE_SSL_CONNECT_ERROR;
1528 connssl->connecting_state = ssl_connect_2;
1529 return CURLE_OK;
1532 static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
1534 char *sep_start, *sep_end, *cert_start, *cert_end;
1535 size_t i, j, err;
1536 size_t len;
1537 unsigned char *b64;
1539 /* Jump through the separators at the beginning of the certificate. */
1540 sep_start = strstr(in, "-----");
1541 if(sep_start == NULL)
1542 return 0;
1543 cert_start = strstr(sep_start + 1, "-----");
1544 if(cert_start == NULL)
1545 return -1;
1547 cert_start += 5;
1549 /* Find separator after the end of the certificate. */
1550 cert_end = strstr(cert_start, "-----");
1551 if(cert_end == NULL)
1552 return -1;
1554 sep_end = strstr(cert_end + 1, "-----");
1555 if(sep_end == NULL)
1556 return -1;
1557 sep_end += 5;
1559 len = cert_end - cert_start;
1560 b64 = malloc(len + 1);
1561 if(!b64)
1562 return -1;
1564 /* Create base64 string without linefeeds. */
1565 for(i = 0, j = 0; i < len; i++) {
1566 if(cert_start[i] != '\r' && cert_start[i] != '\n')
1567 b64[j++] = cert_start[i];
1569 b64[j] = '\0';
1571 err = Curl_base64_decode((const char *)b64, out, outlen);
1572 free(b64);
1573 if(err) {
1574 free(*out);
1575 return -1;
1578 return sep_end - in;
1581 static int read_cert(const char *file, unsigned char **out, size_t *outlen)
1583 int fd;
1584 ssize_t n, len = 0, cap = 512;
1585 unsigned char buf[cap], *data;
1587 fd = open(file, 0);
1588 if(fd < 0)
1589 return -1;
1591 data = malloc(cap);
1592 if(!data) {
1593 close(fd);
1594 return -1;
1597 for(;;) {
1598 n = read(fd, buf, sizeof(buf));
1599 if(n < 0) {
1600 close(fd);
1601 free(data);
1602 return -1;
1604 else if(n == 0) {
1605 close(fd);
1606 break;
1609 if(len + n >= cap) {
1610 cap *= 2;
1611 data = realloc(data, cap);
1612 if(!data) {
1613 close(fd);
1614 return -1;
1618 memcpy(data + len, buf, n);
1619 len += n;
1621 data[len] = '\0';
1623 *out = data;
1624 *outlen = len;
1626 return 0;
1629 static int sslerr_to_curlerr(struct SessionHandle *data, int err)
1631 switch(err) {
1632 case errSSLXCertChainInvalid:
1633 failf(data, "SSL certificate problem: Invalid certificate chain");
1634 return CURLE_SSL_CACERT;
1635 case errSSLUnknownRootCert:
1636 failf(data, "SSL certificate problem: Untrusted root certificate");
1637 return CURLE_SSL_CACERT;
1638 case errSSLNoRootCert:
1639 failf(data, "SSL certificate problem: No root certificate");
1640 return CURLE_SSL_CACERT;
1641 case errSSLCertExpired:
1642 failf(data, "SSL certificate problem: Certificate chain had an "
1643 "expired certificate");
1644 return CURLE_SSL_CACERT;
1645 case errSSLBadCert:
1646 failf(data, "SSL certificate problem: Couldn't understand the server "
1647 "certificate format");
1648 return CURLE_SSL_CONNECT_ERROR;
1649 case errSSLHostNameMismatch:
1650 failf(data, "SSL certificate peer hostname mismatch");
1651 return CURLE_PEER_FAILED_VERIFICATION;
1652 default:
1653 failf(data, "SSL unexpected certificate error %d", err);
1654 return CURLE_SSL_CACERT;
1658 static int append_cert_to_array(struct SessionHandle *data,
1659 unsigned char *buf, size_t buflen,
1660 CFMutableArrayRef array)
1662 CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
1663 if(!certdata) {
1664 failf(data, "SSL: failed to allocate array for CA certificate");
1665 return CURLE_OUT_OF_MEMORY;
1668 SecCertificateRef cacert =
1669 SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
1670 CFRelease(certdata);
1671 if(!cacert) {
1672 failf(data, "SSL: failed to create SecCertificate from CA certificate");
1673 return CURLE_SSL_CACERT;
1676 /* Check if cacert is valid. */
1677 CFStringRef subject = CopyCertSubject(cacert);
1678 if(subject) {
1679 char subject_cbuf[128];
1680 memset(subject_cbuf, 0, 128);
1681 if(!CFStringGetCString(subject,
1682 subject_cbuf,
1683 128,
1684 kCFStringEncodingUTF8)) {
1685 CFRelease(cacert);
1686 failf(data, "SSL: invalid CA certificate subject");
1687 return CURLE_SSL_CACERT;
1689 CFRelease(subject);
1691 else {
1692 CFRelease(cacert);
1693 failf(data, "SSL: invalid CA certificate");
1694 return CURLE_SSL_CACERT;
1697 CFArrayAppendValue(array, cacert);
1698 CFRelease(cacert);
1700 return CURLE_OK;
1703 static int verify_cert(const char *cafile, struct SessionHandle *data,
1704 SSLContextRef ctx)
1706 int n = 0, rc;
1707 long res;
1708 unsigned char *certbuf, *der;
1709 size_t buflen, derlen, offset = 0;
1711 if(read_cert(cafile, &certbuf, &buflen) < 0) {
1712 failf(data, "SSL: failed to read or invalid CA certificate");
1713 return CURLE_SSL_CACERT;
1717 * Certbuf now contains the contents of the certificate file, which can be
1718 * - a single DER certificate,
1719 * - a single PEM certificate or
1720 * - a bunch of PEM certificates (certificate bundle).
1722 * Go through certbuf, and convert any PEM certificate in it into DER
1723 * format.
1725 CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
1726 &kCFTypeArrayCallBacks);
1727 if(array == NULL) {
1728 free(certbuf);
1729 failf(data, "SSL: out of memory creating CA certificate array");
1730 return CURLE_OUT_OF_MEMORY;
1733 while(offset < buflen) {
1734 n++;
1737 * Check if the certificate is in PEM format, and convert it to DER. If
1738 * this fails, we assume the certificate is in DER format.
1740 res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
1741 if(res < 0) {
1742 free(certbuf);
1743 CFRelease(array);
1744 failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
1745 n, offset);
1746 return CURLE_SSL_CACERT;
1748 offset += res;
1750 if(res == 0 && offset == 0) {
1751 /* This is not a PEM file, probably a certificate in DER format. */
1752 rc = append_cert_to_array(data, certbuf, buflen, array);
1753 free(certbuf);
1754 if(rc != CURLE_OK) {
1755 CFRelease(array);
1756 return rc;
1758 break;
1760 else if(res == 0) {
1761 /* No more certificates in the bundle. */
1762 free(certbuf);
1763 break;
1766 rc = append_cert_to_array(data, der, derlen, array);
1767 free(der);
1768 if(rc != CURLE_OK) {
1769 free(certbuf);
1770 CFRelease(array);
1771 return rc;
1775 SecTrustRef trust;
1776 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
1777 if(trust == NULL) {
1778 failf(data, "SSL: error getting certificate chain");
1779 CFRelease(array);
1780 return CURLE_OUT_OF_MEMORY;
1782 else if(ret != noErr) {
1783 CFRelease(array);
1784 return sslerr_to_curlerr(data, ret);
1787 ret = SecTrustSetAnchorCertificates(trust, array);
1788 if(ret != noErr) {
1789 CFRelease(trust);
1790 return sslerr_to_curlerr(data, ret);
1792 ret = SecTrustSetAnchorCertificatesOnly(trust, true);
1793 if(ret != noErr) {
1794 CFRelease(trust);
1795 return sslerr_to_curlerr(data, ret);
1798 SecTrustResultType trust_eval = 0;
1799 ret = SecTrustEvaluate(trust, &trust_eval);
1800 CFRelease(array);
1801 CFRelease(trust);
1802 if(ret != noErr) {
1803 return sslerr_to_curlerr(data, ret);
1806 switch (trust_eval) {
1807 case kSecTrustResultUnspecified:
1808 case kSecTrustResultProceed:
1809 return CURLE_OK;
1811 case kSecTrustResultRecoverableTrustFailure:
1812 case kSecTrustResultDeny:
1813 default:
1814 failf(data, "SSL: certificate verification failed (result: %d)",
1815 trust_eval);
1816 return CURLE_PEER_FAILED_VERIFICATION;
1820 static CURLcode
1821 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1823 struct SessionHandle *data = conn->data;
1824 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1825 OSStatus err;
1826 SSLCipherSuite cipher;
1827 SSLProtocol protocol = 0;
1829 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1830 || ssl_connect_2_reading == connssl->connecting_state
1831 || ssl_connect_2_writing == connssl->connecting_state);
1833 /* Here goes nothing: */
1834 err = SSLHandshake(connssl->ssl_ctx);
1836 if(err != noErr) {
1837 switch (err) {
1838 case errSSLWouldBlock: /* they're not done with us yet */
1839 connssl->connecting_state = connssl->ssl_direction ?
1840 ssl_connect_2_writing : ssl_connect_2_reading;
1841 return CURLE_OK;
1843 /* The below is errSSLServerAuthCompleted; it's not defined in
1844 Leopard's headers */
1845 case -9841:
1846 if(data->set.str[STRING_SSL_CAFILE]) {
1847 int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
1848 connssl->ssl_ctx);
1849 if(res != CURLE_OK)
1850 return res;
1852 /* the documentation says we need to call SSLHandshake() again */
1853 return darwinssl_connect_step2(conn, sockindex);
1855 /* These are all certificate problems with the server: */
1856 case errSSLXCertChainInvalid:
1857 failf(data, "SSL certificate problem: Invalid certificate chain");
1858 return CURLE_SSL_CACERT;
1859 case errSSLUnknownRootCert:
1860 failf(data, "SSL certificate problem: Untrusted root certificate");
1861 return CURLE_SSL_CACERT;
1862 case errSSLNoRootCert:
1863 failf(data, "SSL certificate problem: No root certificate");
1864 return CURLE_SSL_CACERT;
1865 case errSSLCertExpired:
1866 failf(data, "SSL certificate problem: Certificate chain had an "
1867 "expired certificate");
1868 return CURLE_SSL_CACERT;
1869 case errSSLBadCert:
1870 failf(data, "SSL certificate problem: Couldn't understand the server "
1871 "certificate format");
1872 return CURLE_SSL_CONNECT_ERROR;
1874 /* These are all certificate problems with the client: */
1875 case errSecAuthFailed:
1876 failf(data, "SSL authentication failed");
1877 return CURLE_SSL_CONNECT_ERROR;
1878 case errSSLPeerHandshakeFail:
1879 failf(data, "SSL peer handshake failed, the server most likely "
1880 "requires a client certificate to connect");
1881 return CURLE_SSL_CONNECT_ERROR;
1882 case errSSLPeerUnknownCA:
1883 failf(data, "SSL server rejected the client certificate due to "
1884 "the certificate being signed by an unknown certificate "
1885 "authority");
1886 return CURLE_SSL_CONNECT_ERROR;
1888 /* This error is raised if the server's cert didn't match the server's
1889 host name: */
1890 case errSSLHostNameMismatch:
1891 failf(data, "SSL certificate peer verification failed, the "
1892 "certificate did not match \"%s\"\n", conn->host.dispname);
1893 return CURLE_PEER_FAILED_VERIFICATION;
1895 /* Generic handshake errors: */
1896 case errSSLConnectionRefused:
1897 failf(data, "Server dropped the connection during the SSL handshake");
1898 return CURLE_SSL_CONNECT_ERROR;
1899 case errSSLClosedAbort:
1900 failf(data, "Server aborted the SSL handshake");
1901 return CURLE_SSL_CONNECT_ERROR;
1902 case errSSLNegotiation:
1903 failf(data, "Could not negotiate an SSL cipher suite with the server");
1904 return CURLE_SSL_CONNECT_ERROR;
1905 /* Sometimes paramErr happens with buggy ciphers: */
1906 case paramErr: case errSSLInternal:
1907 failf(data, "Internal SSL engine error encountered during the "
1908 "SSL handshake");
1909 return CURLE_SSL_CONNECT_ERROR;
1910 case errSSLFatalAlert:
1911 failf(data, "Fatal SSL engine error encountered during the SSL "
1912 "handshake");
1913 return CURLE_SSL_CONNECT_ERROR;
1914 default:
1915 failf(data, "Unknown SSL protocol error in connection to %s:%d",
1916 conn->host.name, err);
1917 return CURLE_SSL_CONNECT_ERROR;
1920 else {
1921 /* we have been connected fine, we're not waiting for anything else. */
1922 connssl->connecting_state = ssl_connect_3;
1924 /* Informational message */
1925 (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1926 (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1927 switch (protocol) {
1928 case kSSLProtocol2:
1929 infof(data, "SSL 2.0 connection using %s\n",
1930 SSLCipherNameForNumber(cipher));
1931 break;
1932 case kSSLProtocol3:
1933 infof(data, "SSL 3.0 connection using %s\n",
1934 SSLCipherNameForNumber(cipher));
1935 break;
1936 case kTLSProtocol1:
1937 infof(data, "TLS 1.0 connection using %s\n",
1938 TLSCipherNameForNumber(cipher));
1939 break;
1940 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1941 case kTLSProtocol11:
1942 infof(data, "TLS 1.1 connection using %s\n",
1943 TLSCipherNameForNumber(cipher));
1944 break;
1945 case kTLSProtocol12:
1946 infof(data, "TLS 1.2 connection using %s\n",
1947 TLSCipherNameForNumber(cipher));
1948 break;
1949 #endif
1950 default:
1951 infof(data, "Unknown protocol connection\n");
1952 break;
1955 return CURLE_OK;
1959 static CURLcode
1960 darwinssl_connect_step3(struct connectdata *conn,
1961 int sockindex)
1963 struct SessionHandle *data = conn->data;
1964 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1965 CFStringRef server_cert_summary;
1966 char server_cert_summary_c[128];
1967 CFArrayRef server_certs = NULL;
1968 SecCertificateRef server_cert;
1969 OSStatus err;
1970 CFIndex i, count;
1971 SecTrustRef trust = NULL;
1973 /* There is no step 3!
1974 * Well, okay, if verbose mode is on, let's print the details of the
1975 * server certificates. */
1976 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1977 #if CURL_BUILD_IOS
1978 #pragma unused(server_certs)
1979 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1980 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1981 a null trust, so be on guard for that: */
1982 if(err == noErr && trust) {
1983 count = SecTrustGetCertificateCount(trust);
1984 for(i = 0L ; i < count ; i++) {
1985 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1986 server_cert_summary = CopyCertSubject(server_cert);
1987 memset(server_cert_summary_c, 0, 128);
1988 if(CFStringGetCString(server_cert_summary,
1989 server_cert_summary_c,
1990 128,
1991 kCFStringEncodingUTF8)) {
1992 infof(data, "Server certificate: %s\n", server_cert_summary_c);
1994 CFRelease(server_cert_summary);
1996 CFRelease(trust);
1998 #else
1999 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
2000 The function SecTrustGetCertificateAtIndex() is officially present
2001 in Lion, but it is unfortunately also present in Snow Leopard as
2002 private API and doesn't work as expected. So we have to look for
2003 a different symbol to make sure this code is only executed under
2004 Lion or later. */
2005 if(SecTrustEvaluateAsync != NULL) {
2006 #pragma unused(server_certs)
2007 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
2008 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2009 a null trust, so be on guard for that: */
2010 if(err == noErr && trust) {
2011 count = SecTrustGetCertificateCount(trust);
2012 for(i = 0L ; i < count ; i++) {
2013 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2014 server_cert_summary = CopyCertSubject(server_cert);
2015 memset(server_cert_summary_c, 0, 128);
2016 if(CFStringGetCString(server_cert_summary,
2017 server_cert_summary_c,
2018 128,
2019 kCFStringEncodingUTF8)) {
2020 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2022 CFRelease(server_cert_summary);
2024 CFRelease(trust);
2027 else {
2028 #if CURL_SUPPORT_MAC_10_8
2029 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
2030 /* Just in case SSLCopyPeerCertificates() returns null too... */
2031 if(err == noErr && server_certs) {
2032 count = CFArrayGetCount(server_certs);
2033 for(i = 0L ; i < count ; i++) {
2034 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
2037 server_cert_summary = CopyCertSubject(server_cert);
2038 memset(server_cert_summary_c, 0, 128);
2039 if(CFStringGetCString(server_cert_summary,
2040 server_cert_summary_c,
2041 128,
2042 kCFStringEncodingUTF8)) {
2043 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2045 CFRelease(server_cert_summary);
2047 CFRelease(server_certs);
2049 #endif /* CURL_SUPPORT_MAC_10_8 */
2051 #endif /* CURL_BUILD_IOS */
2052 #else
2053 #pragma unused(trust)
2054 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
2055 if(err == noErr) {
2056 count = CFArrayGetCount(server_certs);
2057 for(i = 0L ; i < count ; i++) {
2058 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
2059 server_cert_summary = CopyCertSubject(server_cert);
2060 memset(server_cert_summary_c, 0, 128);
2061 if(CFStringGetCString(server_cert_summary,
2062 server_cert_summary_c,
2063 128,
2064 kCFStringEncodingUTF8)) {
2065 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2067 CFRelease(server_cert_summary);
2069 CFRelease(server_certs);
2071 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
2073 connssl->connecting_state = ssl_connect_done;
2074 return CURLE_OK;
2077 static Curl_recv darwinssl_recv;
2078 static Curl_send darwinssl_send;
2080 static CURLcode
2081 darwinssl_connect_common(struct connectdata *conn,
2082 int sockindex,
2083 bool nonblocking,
2084 bool *done)
2086 CURLcode result;
2087 struct SessionHandle *data = conn->data;
2088 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2089 curl_socket_t sockfd = conn->sock[sockindex];
2090 long timeout_ms;
2091 int what;
2093 /* check if the connection has already been established */
2094 if(ssl_connection_complete == connssl->state) {
2095 *done = TRUE;
2096 return CURLE_OK;
2099 if(ssl_connect_1==connssl->connecting_state) {
2100 /* Find out how much more time we're allowed */
2101 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2103 if(timeout_ms < 0) {
2104 /* no need to continue if time already is up */
2105 failf(data, "SSL connection timeout");
2106 return CURLE_OPERATION_TIMEDOUT;
2109 result = darwinssl_connect_step1(conn, sockindex);
2110 if(result)
2111 return result;
2114 while(ssl_connect_2 == connssl->connecting_state ||
2115 ssl_connect_2_reading == connssl->connecting_state ||
2116 ssl_connect_2_writing == connssl->connecting_state) {
2118 /* check allowed time left */
2119 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2121 if(timeout_ms < 0) {
2122 /* no need to continue if time already is up */
2123 failf(data, "SSL connection timeout");
2124 return CURLE_OPERATION_TIMEDOUT;
2127 /* if ssl is expecting something, check if it's available. */
2128 if(connssl->connecting_state == ssl_connect_2_reading ||
2129 connssl->connecting_state == ssl_connect_2_writing) {
2131 curl_socket_t writefd = ssl_connect_2_writing ==
2132 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2133 curl_socket_t readfd = ssl_connect_2_reading ==
2134 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2136 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
2137 if(what < 0) {
2138 /* fatal error */
2139 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2140 return CURLE_SSL_CONNECT_ERROR;
2142 else if(0 == what) {
2143 if(nonblocking) {
2144 *done = FALSE;
2145 return CURLE_OK;
2147 else {
2148 /* timeout */
2149 failf(data, "SSL connection timeout");
2150 return CURLE_OPERATION_TIMEDOUT;
2153 /* socket is readable or writable */
2156 /* Run transaction, and return to the caller if it failed or if this
2157 * connection is done nonblocking and this loop would execute again. This
2158 * permits the owner of a multi handle to abort a connection attempt
2159 * before step2 has completed while ensuring that a client using select()
2160 * or epoll() will always have a valid fdset to wait on.
2162 result = darwinssl_connect_step2(conn, sockindex);
2163 if(result || (nonblocking &&
2164 (ssl_connect_2 == connssl->connecting_state ||
2165 ssl_connect_2_reading == connssl->connecting_state ||
2166 ssl_connect_2_writing == connssl->connecting_state)))
2167 return result;
2169 } /* repeat step2 until all transactions are done. */
2172 if(ssl_connect_3 == connssl->connecting_state) {
2173 result = darwinssl_connect_step3(conn, sockindex);
2174 if(result)
2175 return result;
2178 if(ssl_connect_done == connssl->connecting_state) {
2179 connssl->state = ssl_connection_complete;
2180 conn->recv[sockindex] = darwinssl_recv;
2181 conn->send[sockindex] = darwinssl_send;
2182 *done = TRUE;
2184 else
2185 *done = FALSE;
2187 /* Reset our connect state machine */
2188 connssl->connecting_state = ssl_connect_1;
2190 return CURLE_OK;
2193 CURLcode
2194 Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
2195 int sockindex,
2196 bool *done)
2198 return darwinssl_connect_common(conn, sockindex, TRUE, done);
2201 CURLcode
2202 Curl_darwinssl_connect(struct connectdata *conn,
2203 int sockindex)
2205 CURLcode result;
2206 bool done = FALSE;
2208 result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
2210 if(result)
2211 return result;
2213 DEBUGASSERT(done);
2215 return CURLE_OK;
2218 void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
2220 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2222 if(connssl->ssl_ctx) {
2223 (void)SSLClose(connssl->ssl_ctx);
2224 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2225 if(SSLCreateContext != NULL)
2226 CFRelease(connssl->ssl_ctx);
2227 #if CURL_SUPPORT_MAC_10_8
2228 else
2229 (void)SSLDisposeContext(connssl->ssl_ctx);
2230 #endif /* CURL_SUPPORT_MAC_10_8 */
2231 #else
2232 (void)SSLDisposeContext(connssl->ssl_ctx);
2233 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2234 connssl->ssl_ctx = NULL;
2236 connssl->ssl_sockfd = 0;
2239 int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
2241 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2242 struct SessionHandle *data = conn->data;
2243 ssize_t nread;
2244 int what;
2245 int rc;
2246 char buf[120];
2248 if(!connssl->ssl_ctx)
2249 return 0;
2251 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
2252 return 0;
2254 Curl_darwinssl_close(conn, sockindex);
2256 rc = 0;
2258 what = Curl_socket_ready(conn->sock[sockindex],
2259 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
2261 for(;;) {
2262 if(what < 0) {
2263 /* anything that gets here is fatally bad */
2264 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2265 rc = -1;
2266 break;
2269 if(!what) { /* timeout */
2270 failf(data, "SSL shutdown timeout");
2271 break;
2274 /* Something to read, let's do it and hope that it is the close
2275 notify alert from the server. No way to SSL_Read now, so use read(). */
2277 nread = read(conn->sock[sockindex], buf, sizeof(buf));
2279 if(nread < 0) {
2280 failf(data, "read: %s", strerror(errno));
2281 rc = -1;
2284 if(nread <= 0)
2285 break;
2287 what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
2290 return rc;
2293 void Curl_darwinssl_session_free(void *ptr)
2295 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
2296 cached session ID inside the Security framework. There is a private
2297 function that does this, but I don't want to have to explain to you why I
2298 got your application rejected from the App Store due to the use of a
2299 private API, so the best we can do is free up our own char array that we
2300 created way back in darwinssl_connect_step1... */
2301 Curl_safefree(ptr);
2304 size_t Curl_darwinssl_version(char *buffer, size_t size)
2306 return snprintf(buffer, size, "SecureTransport");
2310 * This function uses SSLGetSessionState to determine connection status.
2312 * Return codes:
2313 * 1 means the connection is still in place
2314 * 0 means the connection has been closed
2315 * -1 means the connection status is unknown
2317 int Curl_darwinssl_check_cxn(struct connectdata *conn)
2319 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2320 OSStatus err;
2321 SSLSessionState state;
2323 if(connssl->ssl_ctx) {
2324 err = SSLGetSessionState(connssl->ssl_ctx, &state);
2325 if(err == noErr)
2326 return state == kSSLConnected || state == kSSLHandshake;
2327 return -1;
2329 return 0;
2332 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2333 int connindex)
2335 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2336 OSStatus err;
2337 size_t buffer;
2339 if(connssl->ssl_ctx) { /* SSL is in use */
2340 err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
2341 if(err == noErr)
2342 return buffer > 0UL;
2343 return false;
2345 else
2346 return false;
2349 int Curl_darwinssl_random(unsigned char *entropy,
2350 size_t length)
2352 /* arc4random_buf() isn't available on cats older than Lion, so let's
2353 do this manually for the benefit of the older cats. */
2354 size_t i;
2355 u_int32_t random_number = 0;
2357 for(i = 0 ; i < length ; i++) {
2358 if(i % sizeof(u_int32_t) == 0)
2359 random_number = arc4random();
2360 entropy[i] = random_number & 0xFF;
2361 random_number >>= 8;
2363 i = random_number = 0;
2364 return 0;
2367 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2368 size_t tmplen,
2369 unsigned char *md5sum, /* output */
2370 size_t md5len)
2372 (void)md5len;
2373 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2376 bool Curl_darwinssl_false_start(void) {
2377 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
2378 if(SSLSetSessionOption != NULL)
2379 return TRUE;
2380 #endif
2381 return FALSE;
2384 static ssize_t darwinssl_send(struct connectdata *conn,
2385 int sockindex,
2386 const void *mem,
2387 size_t len,
2388 CURLcode *curlcode)
2390 /*struct SessionHandle *data = conn->data;*/
2391 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2392 size_t processed = 0UL;
2393 OSStatus err;
2395 /* The SSLWrite() function works a little differently than expected. The
2396 fourth argument (processed) is currently documented in Apple's
2397 documentation as: "On return, the length, in bytes, of the data actually
2398 written."
2400 Now, one could interpret that as "written to the socket," but actually,
2401 it returns the amount of data that was written to a buffer internal to
2402 the SSLContextRef instead. So it's possible for SSLWrite() to return
2403 errSSLWouldBlock and a number of bytes "written" because those bytes were
2404 encrypted and written to a buffer, not to the socket.
2406 So if this happens, then we need to keep calling SSLWrite() over and
2407 over again with no new data until it quits returning errSSLWouldBlock. */
2409 /* Do we have buffered data to write from the last time we were called? */
2410 if(connssl->ssl_write_buffered_length) {
2411 /* Write the buffered data: */
2412 err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
2413 switch (err) {
2414 case noErr:
2415 /* processed is always going to be 0 because we didn't write to
2416 the buffer, so return how much was written to the socket */
2417 processed = connssl->ssl_write_buffered_length;
2418 connssl->ssl_write_buffered_length = 0UL;
2419 break;
2420 case errSSLWouldBlock: /* argh, try again */
2421 *curlcode = CURLE_AGAIN;
2422 return -1L;
2423 default:
2424 failf(conn->data, "SSLWrite() returned error %d", err);
2425 *curlcode = CURLE_SEND_ERROR;
2426 return -1L;
2429 else {
2430 /* We've got new data to write: */
2431 err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
2432 if(err != noErr) {
2433 switch (err) {
2434 case errSSLWouldBlock:
2435 /* Data was buffered but not sent, we have to tell the caller
2436 to try sending again, and remember how much was buffered */
2437 connssl->ssl_write_buffered_length = len;
2438 *curlcode = CURLE_AGAIN;
2439 return -1L;
2440 default:
2441 failf(conn->data, "SSLWrite() returned error %d", err);
2442 *curlcode = CURLE_SEND_ERROR;
2443 return -1L;
2447 return (ssize_t)processed;
2450 static ssize_t darwinssl_recv(struct connectdata *conn,
2451 int num,
2452 char *buf,
2453 size_t buffersize,
2454 CURLcode *curlcode)
2456 /*struct SessionHandle *data = conn->data;*/
2457 struct ssl_connect_data *connssl = &conn->ssl[num];
2458 size_t processed = 0UL;
2459 OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
2461 if(err != noErr) {
2462 switch (err) {
2463 case errSSLWouldBlock: /* return how much we read (if anything) */
2464 if(processed)
2465 return (ssize_t)processed;
2466 *curlcode = CURLE_AGAIN;
2467 return -1L;
2468 break;
2470 /* errSSLClosedGraceful - server gracefully shut down the SSL session
2471 errSSLClosedNoNotify - server hung up on us instead of sending a
2472 closure alert notice, read() is returning 0
2473 Either way, inform the caller that the server disconnected. */
2474 case errSSLClosedGraceful:
2475 case errSSLClosedNoNotify:
2476 *curlcode = CURLE_OK;
2477 return -1L;
2478 break;
2480 default:
2481 failf(conn->data, "SSLRead() return error %d", err);
2482 *curlcode = CURLE_RECV_ERROR;
2483 return -1L;
2484 break;
2487 return (ssize_t)processed;
2490 #endif /* USE_DARWINSSL */