1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
10 *
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.
14 *
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.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ***************************************************************************/
23
24 /*
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.
27 */
28
29 #include "curl_setup.h"
30
31 #include "urldata.h" /* for the Curl_easy definition */
32 #include "curl_base64.h"
33 #include "strtok.h"
34
35 #ifdef USE_DARWINSSL
36
37 #ifdef HAVE_LIMITS_H
38 #include <limits.h>
39 #endif
40
41 #include <Security/Security.h>
42 #include <Security/SecureTransport.h>
43 #include <CoreFoundation/CoreFoundation.h>
44 #include <CommonCrypto/CommonDigest.h>
45
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.
49
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))
53
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 */
57
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
76
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
90
91 #else
92 #error "The darwinssl back-end requires iOS or OS X."
93 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
94
95 #if CURL_BUILD_MAC
96 #include <sys/sysctl.h>
97 #endif /* CURL_BUILD_MAC */
98
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"
107
108 #include "curl_memory.h"
109 /* The last #include file should be: */
110 #include "memdebug.h"
111
112 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
113 #define ioErr -36
114 #define paramErr -50
115
116 /* The following two functions were ripped from Apple sample code,
117 * with some modifications: */
SocketRead(SSLConnectionRef connection,void * data,size_t * dataLength)118 static OSStatus SocketRead(SSLConnectionRef connection,
119 void *data, /* owned by
120 * caller, data
121 * RETURNED */
122 size_t *dataLength) /* IN/OUT */
123 {
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;
134
135 *dataLength = 0;
136
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;
146 }
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;
163 }
164 break;
165 }
166 else {
167 bytesRead = rrtn;
168 }
169 bytesToGo -= bytesRead;
170 currData += bytesRead;
171
172 if(bytesToGo == 0) {
173 /* filled buffer with incoming data, done */
174 break;
175 }
176 }
177 *dataLength = initLen - bytesToGo;
178
179 return rtn;
180 }
181
SocketWrite(SSLConnectionRef connection,const void * data,size_t * dataLength)182 static OSStatus SocketWrite(SSLConnectionRef connection,
183 const void *data,
184 size_t *dataLength) /* IN/OUT */
185 {
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;
195
196 *dataLength = 0;
197
198 do {
199 length = write(sock,
200 (char*)dataPtr + bytesSent,
201 dataLen - bytesSent);
202 } while((length > 0) &&
203 ( (bytesSent += length) < dataLen) );
204
205 if(length <= 0) {
206 theErr = errno;
207 if(theErr == EAGAIN) {
208 ortn = errSSLWouldBlock;
209 connssl->ssl_direction = true;
210 }
211 else {
212 ortn = ioErr;
213 }
214 }
215 else {
216 ortn = noErr;
217 }
218 *dataLength = bytesSent;
219 return ortn;
220 }
221
SSLCipherNameForNumber(SSLCipherSuite cipher)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;
363 }
364 return "SSL_NULL_WITH_NULL_NULL";
365 }
366
TLSCipherNameForNumber(SSLCipherSuite cipher)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 */
774 }
775 return "TLS_NULL_WITH_NULL_NULL";
776 }
777
778 #if CURL_BUILD_MAC
GetDarwinVersionNumber(int * major,int * minor)779 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
780 {
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;
786
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;
798 }
799
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);
806 }
807 #endif /* CURL_BUILD_MAC */
808
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. */
CopyCertSubject(SecCertificateRef cert)813 CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
814 {
815 CFStringRef server_cert_summary = CFSTR("(null)");
816
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;
838 }
839
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: */
CopyIdentityWithLabelOldSchool(char * label,SecIdentityRef * out_c_a_k)843 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
844 SecIdentityRef *out_c_a_k)
845 {
846 OSStatus status = errSecItemNotFound;
847 SecKeychainAttributeList attr_list;
848 SecKeychainAttribute attr;
849 SecKeychainSearchRef search = NULL;
850 SecCertificateRef cert = NULL;
851
852 /* Set up the attribute list: */
853 attr_list.count = 1L;
854 attr_list.attr = &attr;
855
856 /* Set up our lone search criterion: */
857 attr.tag = kSecLabelItemAttr;
858 attr.data = label;
859 attr.length = (UInt32)strlen(label);
860
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);
873 }
874 }
875
876 if(search)
877 CFRelease(search);
878 return status;
879 }
880 #endif /* CURL_SUPPORT_MAC_10_6 */
881
CopyIdentityWithLabel(char * label,SecIdentityRef * out_cert_and_key)882 static OSStatus CopyIdentityWithLabel(char *label,
883 SecIdentityRef *out_cert_and_key)
884 {
885 OSStatus status = errSecItemNotFound;
886
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);
897
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);
914
915 /* Do we have a match? */
916 status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
917 CFRelease(query_dict);
918 }
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 */
924 }
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;
931 }
932
CopyIdentityFromPKCS12File(const char * cPath,const char * cPassword,SecIdentityRef * out_cert_and_key)933 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
934 const char *cPassword,
935 SecIdentityRef *out_cert_and_key)
936 {
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;
943
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;
955
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);
962
963 /* Retain the identity; we don't care about any other data... */
964 CFRetain(temp_identity);
965 *out_cert_and_key = (SecIdentityRef)temp_identity;
966 }
967
968 if(items)
969 CFRelease(items);
970 CFRelease(options);
971 CFRelease(pkcs_data);
972 }
973 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
974 if(password)
975 CFRelease(password);
976 CFRelease(pkcs_url);
977 return status;
978 }
979
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.
983 *
984 * returns 1 for a file
985 * returns 0 for not a file
986 */
is_file(const char * filename)987 CF_INLINE bool is_file(const char *filename)
988 {
989 struct_stat st;
990
991 if(filename == NULL)
992 return false;
993
994 if(stat(filename, &st) == 0)
995 return S_ISREG(st.st_mode);
996 return false;
997 }
998
darwinssl_connect_step1(struct connectdata * conn,int sockindex)999 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
1000 int sockindex)
1001 {
1002 struct Curl_easy *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 OSStatus err = noErr;
1013 #if CURL_BUILD_MAC
1014 int darwinver_maj = 0, darwinver_min = 0;
1015
1016 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1017 #endif /* CURL_BUILD_MAC */
1018
1019 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1020 if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
1021 if(connssl->ssl_ctx)
1022 CFRelease(connssl->ssl_ctx);
1023 connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1024 if(!connssl->ssl_ctx) {
1025 failf(data, "SSL: couldn't create a context!");
1026 return CURLE_OUT_OF_MEMORY;
1027 }
1028 }
1029 else {
1030 /* The old ST API does not exist under iOS, so don't compile it: */
1031 #if CURL_SUPPORT_MAC_10_8
1032 if(connssl->ssl_ctx)
1033 (void)SSLDisposeContext(connssl->ssl_ctx);
1034 err = SSLNewContext(false, &(connssl->ssl_ctx));
1035 if(err != noErr) {
1036 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1037 return CURLE_OUT_OF_MEMORY;
1038 }
1039 #endif /* CURL_SUPPORT_MAC_10_8 */
1040 }
1041 #else
1042 if(connssl->ssl_ctx)
1043 (void)SSLDisposeContext(connssl->ssl_ctx);
1044 err = SSLNewContext(false, &(connssl->ssl_ctx));
1045 if(err != noErr) {
1046 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1047 return CURLE_OUT_OF_MEMORY;
1048 }
1049 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1050 connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1051
1052 /* check to see if we've been told to use an explicit SSL/TLS version */
1053 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1054 if(SSLSetProtocolVersionMax != NULL) {
1055 switch(data->set.ssl.version) {
1056 default:
1057 case CURL_SSLVERSION_DEFAULT:
1058 case CURL_SSLVERSION_TLSv1:
1059 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1060 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1061 break;
1062 case CURL_SSLVERSION_TLSv1_0:
1063 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1064 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
1065 break;
1066 case CURL_SSLVERSION_TLSv1_1:
1067 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
1068 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
1069 break;
1070 case CURL_SSLVERSION_TLSv1_2:
1071 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
1072 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1073 break;
1074 case CURL_SSLVERSION_SSLv3:
1075 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1076 if(err != noErr) {
1077 failf(data, "Your version of the OS does not support SSLv3");
1078 return CURLE_SSL_CONNECT_ERROR;
1079 }
1080 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
1081 break;
1082 case CURL_SSLVERSION_SSLv2:
1083 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
1084 if(err != noErr) {
1085 failf(data, "Your version of the OS does not support SSLv2");
1086 return CURLE_SSL_CONNECT_ERROR;
1087 }
1088 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
1089 }
1090 }
1091 else {
1092 #if CURL_SUPPORT_MAC_10_8
1093 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1094 kSSLProtocolAll,
1095 false);
1096 switch (data->set.ssl.version) {
1097 default:
1098 case CURL_SSLVERSION_DEFAULT:
1099 case CURL_SSLVERSION_TLSv1:
1100 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1101 kTLSProtocol1,
1102 true);
1103 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1104 kTLSProtocol11,
1105 true);
1106 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1107 kTLSProtocol12,
1108 true);
1109 break;
1110 case CURL_SSLVERSION_TLSv1_0:
1111 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1112 kTLSProtocol1,
1113 true);
1114 break;
1115 case CURL_SSLVERSION_TLSv1_1:
1116 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1117 kTLSProtocol11,
1118 true);
1119 break;
1120 case CURL_SSLVERSION_TLSv1_2:
1121 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1122 kTLSProtocol12,
1123 true);
1124 break;
1125 case CURL_SSLVERSION_SSLv3:
1126 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1127 kSSLProtocol3,
1128 true);
1129 if(err != noErr) {
1130 failf(data, "Your version of the OS does not support SSLv3");
1131 return CURLE_SSL_CONNECT_ERROR;
1132 }
1133 break;
1134 case CURL_SSLVERSION_SSLv2:
1135 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1136 kSSLProtocol2,
1137 true);
1138 if(err != noErr) {
1139 failf(data, "Your version of the OS does not support SSLv2");
1140 return CURLE_SSL_CONNECT_ERROR;
1141 }
1142 break;
1143 }
1144 #endif /* CURL_SUPPORT_MAC_10_8 */
1145 }
1146 #else
1147 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
1148 switch(data->set.ssl.version) {
1149 default:
1150 case CURL_SSLVERSION_DEFAULT:
1151 case CURL_SSLVERSION_TLSv1:
1152 case CURL_SSLVERSION_TLSv1_0:
1153 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1154 kTLSProtocol1,
1155 true);
1156 break;
1157 case CURL_SSLVERSION_TLSv1_1:
1158 failf(data, "Your version of the OS does not support TLSv1.1");
1159 return CURLE_SSL_CONNECT_ERROR;
1160 case CURL_SSLVERSION_TLSv1_2:
1161 failf(data, "Your version of the OS does not support TLSv1.2");
1162 return CURLE_SSL_CONNECT_ERROR;
1163 case CURL_SSLVERSION_SSLv2:
1164 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1165 kSSLProtocol2,
1166 true);
1167 if(err != noErr) {
1168 failf(data, "Your version of the OS does not support SSLv2");
1169 return CURLE_SSL_CONNECT_ERROR;
1170 }
1171 break;
1172 case CURL_SSLVERSION_SSLv3:
1173 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1174 kSSLProtocol3,
1175 true);
1176 if(err != noErr) {
1177 failf(data, "Your version of the OS does not support SSLv3");
1178 return CURLE_SSL_CONNECT_ERROR;
1179 }
1180 break;
1181 }
1182 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1183
1184 if(data->set.str[STRING_KEY]) {
1185 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1186 "Transport. The private key must be in the Keychain.\n");
1187 }
1188
1189 if(data->set.str[STRING_CERT]) {
1190 SecIdentityRef cert_and_key = NULL;
1191 bool is_cert_file = is_file(data->set.str[STRING_CERT]);
1192
1193 /* User wants to authenticate with a client cert. Look for it:
1194 If we detect that this is a file on disk, then let's load it.
1195 Otherwise, assume that the user wants to use an identity loaded
1196 from the Keychain. */
1197 if(is_cert_file) {
1198 if(!data->set.str[STRING_CERT_TYPE])
1199 infof(data, "WARNING: SSL: Certificate type not set, assuming "
1200 "PKCS#12 format.\n");
1201 else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
1202 strlen(data->set.str[STRING_CERT_TYPE])) != 0)
1203 infof(data, "WARNING: SSL: The Security framework only supports "
1204 "loading identities that are in PKCS#12 format.\n");
1205
1206 err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
1207 data->set.str[STRING_KEY_PASSWD], &cert_and_key);
1208 }
1209 else
1210 err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
1211
1212 if(err == noErr) {
1213 SecCertificateRef cert = NULL;
1214 CFTypeRef certs_c[1];
1215 CFArrayRef certs;
1216
1217 /* If we found one, print it out: */
1218 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1219 if(err == noErr) {
1220 CFStringRef cert_summary = CopyCertSubject(cert);
1221 char cert_summary_c[128];
1222
1223 if(cert_summary) {
1224 memset(cert_summary_c, 0, 128);
1225 if(CFStringGetCString(cert_summary,
1226 cert_summary_c,
1227 128,
1228 kCFStringEncodingUTF8)) {
1229 infof(data, "Client certificate: %s\n", cert_summary_c);
1230 }
1231 CFRelease(cert_summary);
1232 CFRelease(cert);
1233 }
1234 }
1235 certs_c[0] = cert_and_key;
1236 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1237 &kCFTypeArrayCallBacks);
1238 err = SSLSetCertificate(connssl->ssl_ctx, certs);
1239 if(certs)
1240 CFRelease(certs);
1241 if(err != noErr) {
1242 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1243 return CURLE_SSL_CERTPROBLEM;
1244 }
1245 CFRelease(cert_and_key);
1246 }
1247 else {
1248 switch(err) {
1249 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1250 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1251 "and its private key.", data->set.str[STRING_CERT]);
1252 break;
1253 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1254 failf(data, "SSL: Couldn't make sense of the data in the "
1255 "certificate \"%s\" and its private key.",
1256 data->set.str[STRING_CERT]);
1257 break;
1258 case -25260: /* errSecPassphraseRequired */
1259 failf(data, "SSL The certificate \"%s\" requires a password.",
1260 data->set.str[STRING_CERT]);
1261 break;
1262 case errSecItemNotFound:
1263 failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1264 "key in the Keychain.", data->set.str[STRING_CERT]);
1265 break;
1266 default:
1267 failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1268 "key: OSStatus %d", data->set.str[STRING_CERT], err);
1269 break;
1270 }
1271 return CURLE_SSL_CERTPROBLEM;
1272 }
1273 }
1274
1275 /* SSL always tries to verify the peer, this only says whether it should
1276 * fail to connect if the verification fails, or if it should continue
1277 * anyway. In the latter case the result of the verification is checked with
1278 * SSL_get_verify_result() below. */
1279 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1280 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1281 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1282 works, it doesn't work as expected under Snow Leopard, Lion or
1283 Mountain Lion.
1284 So we need to call SSLSetEnableCertVerify() on those older cats in order
1285 to disable certificate validation if the user turned that off.
1286 (SecureTransport will always validate the certificate chain by
1287 default.)
1288 Note:
1289 Darwin 11.x.x is Lion (10.7)
1290 Darwin 12.x.x is Mountain Lion (10.8)
1291 Darwin 13.x.x is Mavericks (10.9)
1292 Darwin 14.x.x is Yosemite (10.10)
1293 Darwin 15.x.x is El Capitan (10.11)
1294 */
1295 #if CURL_BUILD_MAC
1296 if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
1297 #else
1298 if(SSLSetSessionOption != NULL) {
1299 #endif /* CURL_BUILD_MAC */
1300 bool break_on_auth = !data->set.ssl.verifypeer ||
1301 data->set.str[STRING_SSL_CAFILE];
1302 err = SSLSetSessionOption(connssl->ssl_ctx,
1303 kSSLSessionOptionBreakOnServerAuth,
1304 break_on_auth);
1305 if(err != noErr) {
1306 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1307 return CURLE_SSL_CONNECT_ERROR;
1308 }
1309 }
1310 else {
1311 #if CURL_SUPPORT_MAC_10_8
1312 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1313 data->set.ssl.verifypeer?true:false);
1314 if(err != noErr) {
1315 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1316 return CURLE_SSL_CONNECT_ERROR;
1317 }
1318 #endif /* CURL_SUPPORT_MAC_10_8 */
1319 }
1320 #else
1321 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1322 data->set.ssl.verifypeer?true:false);
1323 if(err != noErr) {
1324 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1325 return CURLE_SSL_CONNECT_ERROR;
1326 }
1327 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1328
1329 if(data->set.str[STRING_SSL_CAFILE]) {
1330 bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
1331
1332 if(!is_cert_file) {
1333 failf(data, "SSL: can't load CA certificate file %s",
1334 data->set.str[STRING_SSL_CAFILE]);
1335 return CURLE_SSL_CACERT_BADFILE;
1336 }
1337 if(!data->set.ssl.verifypeer) {
1338 failf(data, "SSL: CA certificate set, but certificate verification "
1339 "is disabled");
1340 return CURLE_SSL_CONNECT_ERROR;
1341 }
1342 }
1343
1344 /* Configure hostname check. SNI is used if available.
1345 * Both hostname check and SNI require SSLSetPeerDomainName().
1346 * Also: the verifyhost setting influences SNI usage */
1347 if(data->set.ssl.verifyhost) {
1348 err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1349 strlen(conn->host.name));
1350
1351 if(err != noErr) {
1352 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1353 err);
1354 }
1355
1356 if((Curl_inet_pton(AF_INET, conn->host.name, &addr))
1357 #ifdef ENABLE_IPV6
1358 || (Curl_inet_pton(AF_INET6, conn->host.name, &addr))
1359 #endif
1360 ) {
1361 infof(data, "WARNING: using IP address, SNI is being disabled by "
1362 "the OS.\n");
1363 }
1364 }
1365
1366 /* Disable cipher suites that ST supports but are not safe. These ciphers
1367 are unlikely to be used in any case since ST gives other ciphers a much
1368 higher priority, but it's probably better that we not connect at all than
1369 to give the user a false sense of security if the server only supports
1370 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1371 (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1372 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1373 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1374 if(all_ciphers && allowed_ciphers &&
1375 SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1376 &all_ciphers_count) == noErr) {
1377 for(i = 0UL ; i < all_ciphers_count ; i++) {
1378 #if CURL_BUILD_MAC
1379 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1380 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1381 Work around the problem here by disabling those ciphers if we are
1382 running in an affected version of OS X. */
1383 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1384 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1385 continue;
1386 }
1387 #endif /* CURL_BUILD_MAC */
1388 switch(all_ciphers[i]) {
1389 /* Disable NULL ciphersuites: */
1390 case SSL_NULL_WITH_NULL_NULL:
1391 case SSL_RSA_WITH_NULL_MD5:
1392 case SSL_RSA_WITH_NULL_SHA:
1393 case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1394 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1395 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1396 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1397 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1398 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1399 case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1400 case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1401 case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1402 case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1403 case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1404 case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1405 case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1406 case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1407 case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1408 /* Disable anonymous ciphersuites: */
1409 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1410 case SSL_DH_anon_WITH_RC4_128_MD5:
1411 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1412 case SSL_DH_anon_WITH_DES_CBC_SHA:
1413 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1414 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1415 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1416 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1417 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1418 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1419 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1420 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1421 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1422 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1423 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1424 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1425 /* Disable weak key ciphersuites: */
1426 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1427 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1428 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1429 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1430 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1431 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1432 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1433 case SSL_RSA_WITH_DES_CBC_SHA:
1434 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1435 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1436 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1437 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1438 /* Disable IDEA: */
1439 case SSL_RSA_WITH_IDEA_CBC_SHA:
1440 case SSL_RSA_WITH_IDEA_CBC_MD5:
1441 break;
1442 default: /* enable everything else */
1443 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1444 break;
1445 }
1446 }
1447 err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1448 allowed_ciphers_count);
1449 if(err != noErr) {
1450 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1451 return CURLE_SSL_CONNECT_ERROR;
1452 }
1453 }
1454 else {
1455 Curl_safefree(all_ciphers);
1456 Curl_safefree(allowed_ciphers);
1457 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1458 return CURLE_OUT_OF_MEMORY;
1459 }
1460 Curl_safefree(all_ciphers);
1461 Curl_safefree(allowed_ciphers);
1462
1463 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1464 /* We want to enable 1/n-1 when using a CBC cipher unless the user
1465 specifically doesn't want us doing that: */
1466 if(SSLSetSessionOption != NULL) {
1467 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1468 !data->set.ssl_enable_beast);
1469 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
1470 data->set.ssl.falsestart); /* false start support */
1471 }
1472 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1473
1474 /* Check if there's a cached ID we can/should use here! */
1475 if(conn->ssl_config.sessionid) {
1476 char *ssl_sessionid;
1477 size_t ssl_sessionid_len;
1478
1479 Curl_ssl_sessionid_lock(conn);
1480 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1481 &ssl_sessionid_len)) {
1482 /* we got a session id, use it! */
1483 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1484 Curl_ssl_sessionid_unlock(conn);
1485 if(err != noErr) {
1486 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1487 return CURLE_SSL_CONNECT_ERROR;
1488 }
1489 /* Informational message */
1490 infof(data, "SSL re-using session ID\n");
1491 }
1492 /* If there isn't one, then let's make one up! This has to be done prior
1493 to starting the handshake. */
1494 else {
1495 CURLcode result;
1496 ssl_sessionid =
1497 aprintf("%s:%d:%d:%s:%hu", data->set.str[STRING_SSL_CAFILE],
1498 data->set.ssl.verifypeer, data->set.ssl.verifyhost,
1499 conn->host.name, conn->remote_port);
1500 ssl_sessionid_len = strlen(ssl_sessionid);
1501
1502 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1503 if(err != noErr) {
1504 Curl_ssl_sessionid_unlock(conn);
1505 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1506 return CURLE_SSL_CONNECT_ERROR;
1507 }
1508
1509 result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1510 Curl_ssl_sessionid_unlock(conn);
1511 if(result) {
1512 failf(data, "failed to store ssl session");
1513 return result;
1514 }
1515 }
1516 }
1517
1518 err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1519 if(err != noErr) {
1520 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1521 return CURLE_SSL_CONNECT_ERROR;
1522 }
1523
1524 /* pass the raw socket into the SSL layers */
1525 /* We need to store the FD in a constant memory address, because
1526 * SSLSetConnection() will not copy that address. I've found that
1527 * conn->sock[sockindex] may change on its own. */
1528 connssl->ssl_sockfd = sockfd;
1529 err = SSLSetConnection(connssl->ssl_ctx, connssl);
1530 if(err != noErr) {
1531 failf(data, "SSL: SSLSetConnection() failed: %d", err);
1532 return CURLE_SSL_CONNECT_ERROR;
1533 }
1534
1535 connssl->connecting_state = ssl_connect_2;
1536 return CURLE_OK;
1537 }
1538
1539 static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
1540 {
1541 char *sep_start, *sep_end, *cert_start, *cert_end;
1542 size_t i, j, err;
1543 size_t len;
1544 unsigned char *b64;
1545
1546 /* Jump through the separators at the beginning of the certificate. */
1547 sep_start = strstr(in, "-----");
1548 if(sep_start == NULL)
1549 return 0;
1550 cert_start = strstr(sep_start + 1, "-----");
1551 if(cert_start == NULL)
1552 return -1;
1553
1554 cert_start += 5;
1555
1556 /* Find separator after the end of the certificate. */
1557 cert_end = strstr(cert_start, "-----");
1558 if(cert_end == NULL)
1559 return -1;
1560
1561 sep_end = strstr(cert_end + 1, "-----");
1562 if(sep_end == NULL)
1563 return -1;
1564 sep_end += 5;
1565
1566 len = cert_end - cert_start;
1567 b64 = malloc(len + 1);
1568 if(!b64)
1569 return -1;
1570
1571 /* Create base64 string without linefeeds. */
1572 for(i = 0, j = 0; i < len; i++) {
1573 if(cert_start[i] != '\r' && cert_start[i] != '\n')
1574 b64[j++] = cert_start[i];
1575 }
1576 b64[j] = '\0';
1577
1578 err = Curl_base64_decode((const char *)b64, out, outlen);
1579 free(b64);
1580 if(err) {
1581 free(*out);
1582 return -1;
1583 }
1584
1585 return sep_end - in;
1586 }
1587
1588 static int read_cert(const char *file, unsigned char **out, size_t *outlen)
1589 {
1590 int fd;
1591 ssize_t n, len = 0, cap = 512;
1592 unsigned char buf[cap], *data;
1593
1594 fd = open(file, 0);
1595 if(fd < 0)
1596 return -1;
1597
1598 data = malloc(cap);
1599 if(!data) {
1600 close(fd);
1601 return -1;
1602 }
1603
1604 for(;;) {
1605 n = read(fd, buf, sizeof(buf));
1606 if(n < 0) {
1607 close(fd);
1608 free(data);
1609 return -1;
1610 }
1611 else if(n == 0) {
1612 close(fd);
1613 break;
1614 }
1615
1616 if(len + n >= cap) {
1617 cap *= 2;
1618 data = realloc(data, cap);
1619 if(!data) {
1620 close(fd);
1621 return -1;
1622 }
1623 }
1624
1625 memcpy(data + len, buf, n);
1626 len += n;
1627 }
1628 data[len] = '\0';
1629
1630 *out = data;
1631 *outlen = len;
1632
1633 return 0;
1634 }
1635
1636 static int sslerr_to_curlerr(struct Curl_easy *data, int err)
1637 {
1638 switch(err) {
1639 case errSSLXCertChainInvalid:
1640 failf(data, "SSL certificate problem: Invalid certificate chain");
1641 return CURLE_SSL_CACERT;
1642 case errSSLUnknownRootCert:
1643 failf(data, "SSL certificate problem: Untrusted root certificate");
1644 return CURLE_SSL_CACERT;
1645 case errSSLNoRootCert:
1646 failf(data, "SSL certificate problem: No root certificate");
1647 return CURLE_SSL_CACERT;
1648 case errSSLCertExpired:
1649 failf(data, "SSL certificate problem: Certificate chain had an "
1650 "expired certificate");
1651 return CURLE_SSL_CACERT;
1652 case errSSLBadCert:
1653 failf(data, "SSL certificate problem: Couldn't understand the server "
1654 "certificate format");
1655 return CURLE_SSL_CONNECT_ERROR;
1656 case errSSLHostNameMismatch:
1657 failf(data, "SSL certificate peer hostname mismatch");
1658 return CURLE_PEER_FAILED_VERIFICATION;
1659 default:
1660 failf(data, "SSL unexpected certificate error %d", err);
1661 return CURLE_SSL_CACERT;
1662 }
1663 }
1664
1665 static int append_cert_to_array(struct Curl_easy *data,
1666 unsigned char *buf, size_t buflen,
1667 CFMutableArrayRef array)
1668 {
1669 CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
1670 if(!certdata) {
1671 failf(data, "SSL: failed to allocate array for CA certificate");
1672 return CURLE_OUT_OF_MEMORY;
1673 }
1674
1675 SecCertificateRef cacert =
1676 SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
1677 CFRelease(certdata);
1678 if(!cacert) {
1679 failf(data, "SSL: failed to create SecCertificate from CA certificate");
1680 return CURLE_SSL_CACERT;
1681 }
1682
1683 /* Check if cacert is valid. */
1684 CFStringRef subject = CopyCertSubject(cacert);
1685 if(subject) {
1686 char subject_cbuf[128];
1687 memset(subject_cbuf, 0, 128);
1688 if(!CFStringGetCString(subject,
1689 subject_cbuf,
1690 128,
1691 kCFStringEncodingUTF8)) {
1692 CFRelease(cacert);
1693 failf(data, "SSL: invalid CA certificate subject");
1694 return CURLE_SSL_CACERT;
1695 }
1696 CFRelease(subject);
1697 }
1698 else {
1699 CFRelease(cacert);
1700 failf(data, "SSL: invalid CA certificate");
1701 return CURLE_SSL_CACERT;
1702 }
1703
1704 CFArrayAppendValue(array, cacert);
1705 CFRelease(cacert);
1706
1707 return CURLE_OK;
1708 }
1709
1710 static int verify_cert(const char *cafile, struct Curl_easy *data,
1711 SSLContextRef ctx)
1712 {
1713 int n = 0, rc;
1714 long res;
1715 unsigned char *certbuf, *der;
1716 size_t buflen, derlen, offset = 0;
1717
1718 if(read_cert(cafile, &certbuf, &buflen) < 0) {
1719 failf(data, "SSL: failed to read or invalid CA certificate");
1720 return CURLE_SSL_CACERT;
1721 }
1722
1723 /*
1724 * Certbuf now contains the contents of the certificate file, which can be
1725 * - a single DER certificate,
1726 * - a single PEM certificate or
1727 * - a bunch of PEM certificates (certificate bundle).
1728 *
1729 * Go through certbuf, and convert any PEM certificate in it into DER
1730 * format.
1731 */
1732 CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
1733 &kCFTypeArrayCallBacks);
1734 if(array == NULL) {
1735 free(certbuf);
1736 failf(data, "SSL: out of memory creating CA certificate array");
1737 return CURLE_OUT_OF_MEMORY;
1738 }
1739
1740 while(offset < buflen) {
1741 n++;
1742
1743 /*
1744 * Check if the certificate is in PEM format, and convert it to DER. If
1745 * this fails, we assume the certificate is in DER format.
1746 */
1747 res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
1748 if(res < 0) {
1749 free(certbuf);
1750 CFRelease(array);
1751 failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
1752 n, offset);
1753 return CURLE_SSL_CACERT;
1754 }
1755 offset += res;
1756
1757 if(res == 0 && offset == 0) {
1758 /* This is not a PEM file, probably a certificate in DER format. */
1759 rc = append_cert_to_array(data, certbuf, buflen, array);
1760 free(certbuf);
1761 if(rc != CURLE_OK) {
1762 CFRelease(array);
1763 return rc;
1764 }
1765 break;
1766 }
1767 else if(res == 0) {
1768 /* No more certificates in the bundle. */
1769 free(certbuf);
1770 break;
1771 }
1772
1773 rc = append_cert_to_array(data, der, derlen, array);
1774 free(der);
1775 if(rc != CURLE_OK) {
1776 free(certbuf);
1777 CFRelease(array);
1778 return rc;
1779 }
1780 }
1781
1782 SecTrustRef trust;
1783 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
1784 if(trust == NULL) {
1785 failf(data, "SSL: error getting certificate chain");
1786 CFRelease(array);
1787 return CURLE_OUT_OF_MEMORY;
1788 }
1789 else if(ret != noErr) {
1790 CFRelease(array);
1791 return sslerr_to_curlerr(data, ret);
1792 }
1793
1794 ret = SecTrustSetAnchorCertificates(trust, array);
1795 if(ret != noErr) {
1796 CFRelease(trust);
1797 return sslerr_to_curlerr(data, ret);
1798 }
1799 ret = SecTrustSetAnchorCertificatesOnly(trust, true);
1800 if(ret != noErr) {
1801 CFRelease(trust);
1802 return sslerr_to_curlerr(data, ret);
1803 }
1804
1805 SecTrustResultType trust_eval = 0;
1806 ret = SecTrustEvaluate(trust, &trust_eval);
1807 CFRelease(array);
1808 CFRelease(trust);
1809 if(ret != noErr) {
1810 return sslerr_to_curlerr(data, ret);
1811 }
1812
1813 switch (trust_eval) {
1814 case kSecTrustResultUnspecified:
1815 case kSecTrustResultProceed:
1816 return CURLE_OK;
1817
1818 case kSecTrustResultRecoverableTrustFailure:
1819 case kSecTrustResultDeny:
1820 default:
1821 failf(data, "SSL: certificate verification failed (result: %d)",
1822 trust_eval);
1823 return CURLE_PEER_FAILED_VERIFICATION;
1824 }
1825 }
1826
1827 static CURLcode
1828 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1829 {
1830 struct Curl_easy *data = conn->data;
1831 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1832 OSStatus err;
1833 SSLCipherSuite cipher;
1834 SSLProtocol protocol = 0;
1835
1836 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
1837 || ssl_connect_2_reading == connssl->connecting_state
1838 || ssl_connect_2_writing == connssl->connecting_state);
1839
1840 /* Here goes nothing: */
1841 err = SSLHandshake(connssl->ssl_ctx);
1842
1843 if(err != noErr) {
1844 switch (err) {
1845 case errSSLWouldBlock: /* they're not done with us yet */
1846 connssl->connecting_state = connssl->ssl_direction ?
1847 ssl_connect_2_writing : ssl_connect_2_reading;
1848 return CURLE_OK;
1849
1850 /* The below is errSSLServerAuthCompleted; it's not defined in
1851 Leopard's headers */
1852 case -9841:
1853 if(data->set.str[STRING_SSL_CAFILE]) {
1854 int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
1855 connssl->ssl_ctx);
1856 if(res != CURLE_OK)
1857 return res;
1858 }
1859 /* the documentation says we need to call SSLHandshake() again */
1860 return darwinssl_connect_step2(conn, sockindex);
1861
1862 /* These are all certificate problems with the server: */
1863 case errSSLXCertChainInvalid:
1864 failf(data, "SSL certificate problem: Invalid certificate chain");
1865 return CURLE_SSL_CACERT;
1866 case errSSLUnknownRootCert:
1867 failf(data, "SSL certificate problem: Untrusted root certificate");
1868 return CURLE_SSL_CACERT;
1869 case errSSLNoRootCert:
1870 failf(data, "SSL certificate problem: No root certificate");
1871 return CURLE_SSL_CACERT;
1872 case errSSLCertExpired:
1873 failf(data, "SSL certificate problem: Certificate chain had an "
1874 "expired certificate");
1875 return CURLE_SSL_CACERT;
1876 case errSSLBadCert:
1877 failf(data, "SSL certificate problem: Couldn't understand the server "
1878 "certificate format");
1879 return CURLE_SSL_CONNECT_ERROR;
1880
1881 /* These are all certificate problems with the client: */
1882 case errSecAuthFailed:
1883 failf(data, "SSL authentication failed");
1884 return CURLE_SSL_CONNECT_ERROR;
1885 case errSSLPeerHandshakeFail:
1886 failf(data, "SSL peer handshake failed, the server most likely "
1887 "requires a client certificate to connect");
1888 return CURLE_SSL_CONNECT_ERROR;
1889 case errSSLPeerUnknownCA:
1890 failf(data, "SSL server rejected the client certificate due to "
1891 "the certificate being signed by an unknown certificate "
1892 "authority");
1893 return CURLE_SSL_CONNECT_ERROR;
1894
1895 /* This error is raised if the server's cert didn't match the server's
1896 host name: */
1897 case errSSLHostNameMismatch:
1898 failf(data, "SSL certificate peer verification failed, the "
1899 "certificate did not match \"%s\"\n", conn->host.dispname);
1900 return CURLE_PEER_FAILED_VERIFICATION;
1901
1902 /* Generic handshake errors: */
1903 case errSSLConnectionRefused:
1904 failf(data, "Server dropped the connection during the SSL handshake");
1905 return CURLE_SSL_CONNECT_ERROR;
1906 case errSSLClosedAbort:
1907 failf(data, "Server aborted the SSL handshake");
1908 return CURLE_SSL_CONNECT_ERROR;
1909 case errSSLNegotiation:
1910 failf(data, "Could not negotiate an SSL cipher suite with the server");
1911 return CURLE_SSL_CONNECT_ERROR;
1912 /* Sometimes paramErr happens with buggy ciphers: */
1913 case paramErr: case errSSLInternal:
1914 failf(data, "Internal SSL engine error encountered during the "
1915 "SSL handshake");
1916 return CURLE_SSL_CONNECT_ERROR;
1917 case errSSLFatalAlert:
1918 failf(data, "Fatal SSL engine error encountered during the SSL "
1919 "handshake");
1920 return CURLE_SSL_CONNECT_ERROR;
1921 default:
1922 failf(data, "Unknown SSL protocol error in connection to %s:%d",
1923 conn->host.name, err);
1924 return CURLE_SSL_CONNECT_ERROR;
1925 }
1926 }
1927 else {
1928 /* we have been connected fine, we're not waiting for anything else. */
1929 connssl->connecting_state = ssl_connect_3;
1930
1931 /* Informational message */
1932 (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1933 (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1934 switch (protocol) {
1935 case kSSLProtocol2:
1936 infof(data, "SSL 2.0 connection using %s\n",
1937 SSLCipherNameForNumber(cipher));
1938 break;
1939 case kSSLProtocol3:
1940 infof(data, "SSL 3.0 connection using %s\n",
1941 SSLCipherNameForNumber(cipher));
1942 break;
1943 case kTLSProtocol1:
1944 infof(data, "TLS 1.0 connection using %s\n",
1945 TLSCipherNameForNumber(cipher));
1946 break;
1947 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1948 case kTLSProtocol11:
1949 infof(data, "TLS 1.1 connection using %s\n",
1950 TLSCipherNameForNumber(cipher));
1951 break;
1952 case kTLSProtocol12:
1953 infof(data, "TLS 1.2 connection using %s\n",
1954 TLSCipherNameForNumber(cipher));
1955 break;
1956 #endif
1957 default:
1958 infof(data, "Unknown protocol connection\n");
1959 break;
1960 }
1961
1962 return CURLE_OK;
1963 }
1964 }
1965
1966 static CURLcode
1967 darwinssl_connect_step3(struct connectdata *conn,
1968 int sockindex)
1969 {
1970 struct Curl_easy *data = conn->data;
1971 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1972 CFStringRef server_cert_summary;
1973 char server_cert_summary_c[128];
1974 CFArrayRef server_certs = NULL;
1975 SecCertificateRef server_cert;
1976 OSStatus err;
1977 CFIndex i, count;
1978 SecTrustRef trust = NULL;
1979
1980 /* There is no step 3!
1981 * Well, okay, if verbose mode is on, let's print the details of the
1982 * server certificates. */
1983 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1984 #if CURL_BUILD_IOS
1985 #pragma unused(server_certs)
1986 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1987 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1988 a null trust, so be on guard for that: */
1989 if(err == noErr && trust) {
1990 count = SecTrustGetCertificateCount(trust);
1991 for(i = 0L ; i < count ; i++) {
1992 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1993 server_cert_summary = CopyCertSubject(server_cert);
1994 memset(server_cert_summary_c, 0, 128);
1995 if(CFStringGetCString(server_cert_summary,
1996 server_cert_summary_c,
1997 128,
1998 kCFStringEncodingUTF8)) {
1999 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2000 }
2001 CFRelease(server_cert_summary);
2002 }
2003 CFRelease(trust);
2004 }
2005 #else
2006 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
2007 The function SecTrustGetCertificateAtIndex() is officially present
2008 in Lion, but it is unfortunately also present in Snow Leopard as
2009 private API and doesn't work as expected. So we have to look for
2010 a different symbol to make sure this code is only executed under
2011 Lion or later. */
2012 if(SecTrustEvaluateAsync != NULL) {
2013 #pragma unused(server_certs)
2014 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
2015 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2016 a null trust, so be on guard for that: */
2017 if(err == noErr && trust) {
2018 count = SecTrustGetCertificateCount(trust);
2019 for(i = 0L ; i < count ; i++) {
2020 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2021 server_cert_summary = CopyCertSubject(server_cert);
2022 memset(server_cert_summary_c, 0, 128);
2023 if(CFStringGetCString(server_cert_summary,
2024 server_cert_summary_c,
2025 128,
2026 kCFStringEncodingUTF8)) {
2027 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2028 }
2029 CFRelease(server_cert_summary);
2030 }
2031 CFRelease(trust);
2032 }
2033 }
2034 else {
2035 #if CURL_SUPPORT_MAC_10_8
2036 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
2037 /* Just in case SSLCopyPeerCertificates() returns null too... */
2038 if(err == noErr && server_certs) {
2039 count = CFArrayGetCount(server_certs);
2040 for(i = 0L ; i < count ; i++) {
2041 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
2042 i);
2043
2044 server_cert_summary = CopyCertSubject(server_cert);
2045 memset(server_cert_summary_c, 0, 128);
2046 if(CFStringGetCString(server_cert_summary,
2047 server_cert_summary_c,
2048 128,
2049 kCFStringEncodingUTF8)) {
2050 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2051 }
2052 CFRelease(server_cert_summary);
2053 }
2054 CFRelease(server_certs);
2055 }
2056 #endif /* CURL_SUPPORT_MAC_10_8 */
2057 }
2058 #endif /* CURL_BUILD_IOS */
2059 #else
2060 #pragma unused(trust)
2061 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
2062 if(err == noErr) {
2063 count = CFArrayGetCount(server_certs);
2064 for(i = 0L ; i < count ; i++) {
2065 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
2066 server_cert_summary = CopyCertSubject(server_cert);
2067 memset(server_cert_summary_c, 0, 128);
2068 if(CFStringGetCString(server_cert_summary,
2069 server_cert_summary_c,
2070 128,
2071 kCFStringEncodingUTF8)) {
2072 infof(data, "Server certificate: %s\n", server_cert_summary_c);
2073 }
2074 CFRelease(server_cert_summary);
2075 }
2076 CFRelease(server_certs);
2077 }
2078 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
2079
2080 connssl->connecting_state = ssl_connect_done;
2081 return CURLE_OK;
2082 }
2083
2084 static Curl_recv darwinssl_recv;
2085 static Curl_send darwinssl_send;
2086
2087 static CURLcode
2088 darwinssl_connect_common(struct connectdata *conn,
2089 int sockindex,
2090 bool nonblocking,
2091 bool *done)
2092 {
2093 CURLcode result;
2094 struct Curl_easy *data = conn->data;
2095 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2096 curl_socket_t sockfd = conn->sock[sockindex];
2097 long timeout_ms;
2098 int what;
2099
2100 /* check if the connection has already been established */
2101 if(ssl_connection_complete == connssl->state) {
2102 *done = TRUE;
2103 return CURLE_OK;
2104 }
2105
2106 if(ssl_connect_1==connssl->connecting_state) {
2107 /* Find out how much more time we're allowed */
2108 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2109
2110 if(timeout_ms < 0) {
2111 /* no need to continue if time already is up */
2112 failf(data, "SSL connection timeout");
2113 return CURLE_OPERATION_TIMEDOUT;
2114 }
2115
2116 result = darwinssl_connect_step1(conn, sockindex);
2117 if(result)
2118 return result;
2119 }
2120
2121 while(ssl_connect_2 == connssl->connecting_state ||
2122 ssl_connect_2_reading == connssl->connecting_state ||
2123 ssl_connect_2_writing == connssl->connecting_state) {
2124
2125 /* check allowed time left */
2126 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2127
2128 if(timeout_ms < 0) {
2129 /* no need to continue if time already is up */
2130 failf(data, "SSL connection timeout");
2131 return CURLE_OPERATION_TIMEDOUT;
2132 }
2133
2134 /* if ssl is expecting something, check if it's available. */
2135 if(connssl->connecting_state == ssl_connect_2_reading ||
2136 connssl->connecting_state == ssl_connect_2_writing) {
2137
2138 curl_socket_t writefd = ssl_connect_2_writing ==
2139 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2140 curl_socket_t readfd = ssl_connect_2_reading ==
2141 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2142
2143 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
2144 if(what < 0) {
2145 /* fatal error */
2146 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2147 return CURLE_SSL_CONNECT_ERROR;
2148 }
2149 else if(0 == what) {
2150 if(nonblocking) {
2151 *done = FALSE;
2152 return CURLE_OK;
2153 }
2154 else {
2155 /* timeout */
2156 failf(data, "SSL connection timeout");
2157 return CURLE_OPERATION_TIMEDOUT;
2158 }
2159 }
2160 /* socket is readable or writable */
2161 }
2162
2163 /* Run transaction, and return to the caller if it failed or if this
2164 * connection is done nonblocking and this loop would execute again. This
2165 * permits the owner of a multi handle to abort a connection attempt
2166 * before step2 has completed while ensuring that a client using select()
2167 * or epoll() will always have a valid fdset to wait on.
2168 */
2169 result = darwinssl_connect_step2(conn, sockindex);
2170 if(result || (nonblocking &&
2171 (ssl_connect_2 == connssl->connecting_state ||
2172 ssl_connect_2_reading == connssl->connecting_state ||
2173 ssl_connect_2_writing == connssl->connecting_state)))
2174 return result;
2175
2176 } /* repeat step2 until all transactions are done. */
2177
2178
2179 if(ssl_connect_3 == connssl->connecting_state) {
2180 result = darwinssl_connect_step3(conn, sockindex);
2181 if(result)
2182 return result;
2183 }
2184
2185 if(ssl_connect_done == connssl->connecting_state) {
2186 connssl->state = ssl_connection_complete;
2187 conn->recv[sockindex] = darwinssl_recv;
2188 conn->send[sockindex] = darwinssl_send;
2189 *done = TRUE;
2190 }
2191 else
2192 *done = FALSE;
2193
2194 /* Reset our connect state machine */
2195 connssl->connecting_state = ssl_connect_1;
2196
2197 return CURLE_OK;
2198 }
2199
2200 CURLcode
2201 Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
2202 int sockindex,
2203 bool *done)
2204 {
2205 return darwinssl_connect_common(conn, sockindex, TRUE, done);
2206 }
2207
2208 CURLcode
2209 Curl_darwinssl_connect(struct connectdata *conn,
2210 int sockindex)
2211 {
2212 CURLcode result;
2213 bool done = FALSE;
2214
2215 result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
2216
2217 if(result)
2218 return result;
2219
2220 DEBUGASSERT(done);
2221
2222 return CURLE_OK;
2223 }
2224
2225 void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
2226 {
2227 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2228
2229 if(connssl->ssl_ctx) {
2230 (void)SSLClose(connssl->ssl_ctx);
2231 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2232 if(SSLCreateContext != NULL)
2233 CFRelease(connssl->ssl_ctx);
2234 #if CURL_SUPPORT_MAC_10_8
2235 else
2236 (void)SSLDisposeContext(connssl->ssl_ctx);
2237 #endif /* CURL_SUPPORT_MAC_10_8 */
2238 #else
2239 (void)SSLDisposeContext(connssl->ssl_ctx);
2240 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2241 connssl->ssl_ctx = NULL;
2242 }
2243 connssl->ssl_sockfd = 0;
2244 }
2245
2246 int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
2247 {
2248 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2249 struct Curl_easy *data = conn->data;
2250 ssize_t nread;
2251 int what;
2252 int rc;
2253 char buf[120];
2254
2255 if(!connssl->ssl_ctx)
2256 return 0;
2257
2258 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
2259 return 0;
2260
2261 Curl_darwinssl_close(conn, sockindex);
2262
2263 rc = 0;
2264
2265 what = Curl_socket_ready(conn->sock[sockindex],
2266 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
2267
2268 for(;;) {
2269 if(what < 0) {
2270 /* anything that gets here is fatally bad */
2271 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2272 rc = -1;
2273 break;
2274 }
2275
2276 if(!what) { /* timeout */
2277 failf(data, "SSL shutdown timeout");
2278 break;
2279 }
2280
2281 /* Something to read, let's do it and hope that it is the close
2282 notify alert from the server. No way to SSL_Read now, so use read(). */
2283
2284 nread = read(conn->sock[sockindex], buf, sizeof(buf));
2285
2286 if(nread < 0) {
2287 failf(data, "read: %s", strerror(errno));
2288 rc = -1;
2289 }
2290
2291 if(nread <= 0)
2292 break;
2293
2294 what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
2295 }
2296
2297 return rc;
2298 }
2299
2300 void Curl_darwinssl_session_free(void *ptr)
2301 {
2302 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
2303 cached session ID inside the Security framework. There is a private
2304 function that does this, but I don't want to have to explain to you why I
2305 got your application rejected from the App Store due to the use of a
2306 private API, so the best we can do is free up our own char array that we
2307 created way back in darwinssl_connect_step1... */
2308 Curl_safefree(ptr);
2309 }
2310
2311 size_t Curl_darwinssl_version(char *buffer, size_t size)
2312 {
2313 return snprintf(buffer, size, "SecureTransport");
2314 }
2315
2316 /*
2317 * This function uses SSLGetSessionState to determine connection status.
2318 *
2319 * Return codes:
2320 * 1 means the connection is still in place
2321 * 0 means the connection has been closed
2322 * -1 means the connection status is unknown
2323 */
2324 int Curl_darwinssl_check_cxn(struct connectdata *conn)
2325 {
2326 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2327 OSStatus err;
2328 SSLSessionState state;
2329
2330 if(connssl->ssl_ctx) {
2331 err = SSLGetSessionState(connssl->ssl_ctx, &state);
2332 if(err == noErr)
2333 return state == kSSLConnected || state == kSSLHandshake;
2334 return -1;
2335 }
2336 return 0;
2337 }
2338
2339 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2340 int connindex)
2341 {
2342 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2343 OSStatus err;
2344 size_t buffer;
2345
2346 if(connssl->ssl_ctx) { /* SSL is in use */
2347 err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
2348 if(err == noErr)
2349 return buffer > 0UL;
2350 return false;
2351 }
2352 else
2353 return false;
2354 }
2355
2356 int Curl_darwinssl_random(unsigned char *entropy,
2357 size_t length)
2358 {
2359 /* arc4random_buf() isn't available on cats older than Lion, so let's
2360 do this manually for the benefit of the older cats. */
2361 size_t i;
2362 u_int32_t random_number = 0;
2363
2364 for(i = 0 ; i < length ; i++) {
2365 if(i % sizeof(u_int32_t) == 0)
2366 random_number = arc4random();
2367 entropy[i] = random_number & 0xFF;
2368 random_number >>= 8;
2369 }
2370 i = random_number = 0;
2371 return 0;
2372 }
2373
2374 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2375 size_t tmplen,
2376 unsigned char *md5sum, /* output */
2377 size_t md5len)
2378 {
2379 (void)md5len;
2380 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2381 }
2382
2383 bool Curl_darwinssl_false_start(void) {
2384 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
2385 if(SSLSetSessionOption != NULL)
2386 return TRUE;
2387 #endif
2388 return FALSE;
2389 }
2390
2391 static ssize_t darwinssl_send(struct connectdata *conn,
2392 int sockindex,
2393 const void *mem,
2394 size_t len,
2395 CURLcode *curlcode)
2396 {
2397 /*struct Curl_easy *data = conn->data;*/
2398 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2399 size_t processed = 0UL;
2400 OSStatus err;
2401
2402 /* The SSLWrite() function works a little differently than expected. The
2403 fourth argument (processed) is currently documented in Apple's
2404 documentation as: "On return, the length, in bytes, of the data actually
2405 written."
2406
2407 Now, one could interpret that as "written to the socket," but actually,
2408 it returns the amount of data that was written to a buffer internal to
2409 the SSLContextRef instead. So it's possible for SSLWrite() to return
2410 errSSLWouldBlock and a number of bytes "written" because those bytes were
2411 encrypted and written to a buffer, not to the socket.
2412
2413 So if this happens, then we need to keep calling SSLWrite() over and
2414 over again with no new data until it quits returning errSSLWouldBlock. */
2415
2416 /* Do we have buffered data to write from the last time we were called? */
2417 if(connssl->ssl_write_buffered_length) {
2418 /* Write the buffered data: */
2419 err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
2420 switch (err) {
2421 case noErr:
2422 /* processed is always going to be 0 because we didn't write to
2423 the buffer, so return how much was written to the socket */
2424 processed = connssl->ssl_write_buffered_length;
2425 connssl->ssl_write_buffered_length = 0UL;
2426 break;
2427 case errSSLWouldBlock: /* argh, try again */
2428 *curlcode = CURLE_AGAIN;
2429 return -1L;
2430 default:
2431 failf(conn->data, "SSLWrite() returned error %d", err);
2432 *curlcode = CURLE_SEND_ERROR;
2433 return -1L;
2434 }
2435 }
2436 else {
2437 /* We've got new data to write: */
2438 err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
2439 if(err != noErr) {
2440 switch (err) {
2441 case errSSLWouldBlock:
2442 /* Data was buffered but not sent, we have to tell the caller
2443 to try sending again, and remember how much was buffered */
2444 connssl->ssl_write_buffered_length = len;
2445 *curlcode = CURLE_AGAIN;
2446 return -1L;
2447 default:
2448 failf(conn->data, "SSLWrite() returned error %d", err);
2449 *curlcode = CURLE_SEND_ERROR;
2450 return -1L;
2451 }
2452 }
2453 }
2454 return (ssize_t)processed;
2455 }
2456
2457 static ssize_t darwinssl_recv(struct connectdata *conn,
2458 int num,
2459 char *buf,
2460 size_t buffersize,
2461 CURLcode *curlcode)
2462 {
2463 /*struct Curl_easy *data = conn->data;*/
2464 struct ssl_connect_data *connssl = &conn->ssl[num];
2465 size_t processed = 0UL;
2466 OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
2467
2468 if(err != noErr) {
2469 switch (err) {
2470 case errSSLWouldBlock: /* return how much we read (if anything) */
2471 if(processed)
2472 return (ssize_t)processed;
2473 *curlcode = CURLE_AGAIN;
2474 return -1L;
2475 break;
2476
2477 /* errSSLClosedGraceful - server gracefully shut down the SSL session
2478 errSSLClosedNoNotify - server hung up on us instead of sending a
2479 closure alert notice, read() is returning 0
2480 Either way, inform the caller that the server disconnected. */
2481 case errSSLClosedGraceful:
2482 case errSSLClosedNoNotify:
2483 *curlcode = CURLE_OK;
2484 return -1L;
2485 break;
2486
2487 default:
2488 failf(conn->data, "SSLRead() return error %d", err);
2489 *curlcode = CURLE_RECV_ERROR;
2490 return -1L;
2491 break;
2492 }
2493 }
2494 return (ssize_t)processed;
2495 }
2496
2497 #endif /* USE_DARWINSSL */
2498