source: UsbWattMeter/trunk/curl-7.47.1/lib/vtls/darwinssl.c@ 164

Last change on this file since 164 was 164, checked in by coas-nagasima, 8 years ago

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

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