Bug Summary

File:vtls/curl_darwinssl.c
Location:line 2279, column 3
Description:Value stored to 'i' is never read

Annotated Source Code

1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2012 - 2013, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012 - 2013, 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 http://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
34#ifdef USE_DARWINSSL1
35
36#ifdef HAVE_LIMITS_H1
37#include <limits.h>
38#endif
39
40#include <Security/Security.h>
41#include <Security/SecureTransport.h>
42#include <CoreFoundation/CoreFoundation.h>
43#include <CommonCrypto/CommonDigest.h>
44
45/* The Security framework has changed greatly between iOS and different OS X
46 versions, and we will try to support as many of them as we can (back to
47 Leopard and iOS 5) by using macros and weak-linking.
48
49 IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
50 you must build this project against the 10.8 SDK or later. */
51#if (TARGET_OS_MAC1 && !(TARGET_OS_EMBEDDED0 || TARGET_OS_IPHONE0))
52
53#if MAC_OS_X_VERSION_MAX_ALLOWED1080 < 1050
54#error "The darwinssl back-end requires Leopard or later."
55#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
56
57#define CURL_BUILD_IOS0 0
58#define CURL_BUILD_IOS_70 0
59#define CURL_BUILD_MAC1 1
60/* This is the maximum API level we are allowed to use when building: */
61#define CURL_BUILD_MAC_10_51080 >= 1050 MAC_OS_X_VERSION_MAX_ALLOWED1080 >= 1050
62#define CURL_BUILD_MAC_10_61080 >= 1060 MAC_OS_X_VERSION_MAX_ALLOWED1080 >= 1060
63#define CURL_BUILD_MAC_10_71080 >= 1070 MAC_OS_X_VERSION_MAX_ALLOWED1080 >= 1070
64#define CURL_BUILD_MAC_10_81080 >= 1080 MAC_OS_X_VERSION_MAX_ALLOWED1080 >= 1080
65#define CURL_BUILD_MAC_10_91080 >= 1090 MAC_OS_X_VERSION_MAX_ALLOWED1080 >= 1090
66/* These macros mean "the following code is present to allow runtime backward
67 compatibility with at least this cat or earlier":
68 (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
69 environmental variable.) */
70#define CURL_SUPPORT_MAC_10_51080 <= 1050 MAC_OS_X_VERSION_MIN_REQUIRED1080 <= 1050
71#define CURL_SUPPORT_MAC_10_61080 <= 1060 MAC_OS_X_VERSION_MIN_REQUIRED1080 <= 1060
72#define CURL_SUPPORT_MAC_10_71080 <= 1070 MAC_OS_X_VERSION_MIN_REQUIRED1080 <= 1070
73#define CURL_SUPPORT_MAC_10_81080 <= 1080 MAC_OS_X_VERSION_MIN_REQUIRED1080 <= 1080
74#define CURL_SUPPORT_MAC_10_91080 <= 1090 MAC_OS_X_VERSION_MIN_REQUIRED1080 <= 1090
75
76#elif TARGET_OS_EMBEDDED0 || TARGET_OS_IPHONE0
77#define CURL_BUILD_IOS0 1
78#define CURL_BUILD_IOS_70 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
79#define CURL_BUILD_MAC1 0
80#define CURL_BUILD_MAC_10_51080 >= 1050 0
81#define CURL_BUILD_MAC_10_61080 >= 1060 0
82#define CURL_BUILD_MAC_10_71080 >= 1070 0
83#define CURL_BUILD_MAC_10_81080 >= 1080 0
84#define CURL_SUPPORT_MAC_10_51080 <= 1050 0
85#define CURL_SUPPORT_MAC_10_61080 <= 1060 0
86#define CURL_SUPPORT_MAC_10_71080 <= 1070 0
87#define CURL_SUPPORT_MAC_10_81080 <= 1080 0
88
89#else
90#error "The darwinssl back-end requires iOS or OS X."
91#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
92
93#if CURL_BUILD_MAC1
94#include <sys/sysctl.h>
95#endif /* CURL_BUILD_MAC */
96
97#include "urldata.h"
98#include "sendf.h"
99#include "inet_pton.h"
100#include "connect.h"
101#include "select.h"
102#include "vtls.h"
103#include "curl_darwinssl.h"
104
105#define _MPRINTF_REPLACE /* use our functions only */
106#include <curl/mprintf.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 -36
114#define paramErr-50 -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(*__error());
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 ENOENT2:
150 /* connection closed */
151 rtn = errSSLClosedGraceful;
152 break;
153 case ECONNRESET54:
154 rtn = errSSLClosedAbort;
155 break;
156 case EAGAIN35:
157 rtn = errSSLWouldBlock;
158 connssl->ssl_direction = false0;
159 break;
160 default:
161 rtn = ioErr-36;
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(*__error());
207 if(theErr == EAGAIN35) {
208 ortn = errSSLWouldBlock;
209 connssl->ssl_direction = true1;
210 }
211 else {
212 ortn = ioErr-36;
213 }
214 }
215 else {
216 ortn = noErr;
217 }
218 *dataLength = bytesSent;
219 return ortn;
220}
221
222CF_INLINEstatic __inline__ __attribute__((always_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_INLINEstatic __inline__ __attribute__((always_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_61080 >= 1060 || CURL_BUILD_IOS0
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_81080 >= 1080 || CURL_BUILD_IOS0
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_91080 >= 1090 || CURL_BUILD_IOS_70
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_MAC1
779CF_INLINEstatic __inline__ __attribute__((always_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
786 /* Get the Darwin kernel version from the kernel using sysctl(): */
787 mib[0] = CTL_KERN1;
788 mib[1] = KERN_OSRELEASE2;
789 if(sysctl(mib, 2, NULL((void*)0), &os_version_len, NULL((void*)0), 0) == -1)
790 return;
791 os_version = malloc(os_version_len*sizeof(char))Curl_cmalloc(os_version_len*sizeof(char));
792 if(!os_version)
793 return;
794 if(sysctl(mib, 2, os_version, &os_version_len, NULL((void*)0), 0) == -1) {
795 free(os_version)Curl_cfree(os_version);
796 return;
797 }
798
799 /* Parse the version: */
800 os_version_major = strtok(os_version, ".");
801 os_version_minor = strtok(NULL((void*)0), ".");
802 /*os_version_point = strtok(NULL, ".");*/
803 *major = atoi(os_version_major);
804 *minor = atoi(os_version_minor);
805 free(os_version)Curl_cfree(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. */
813CF_INLINEstatic __inline__ __attribute__((always_inline)) CFStringRef CopyCertSubject(SecCertificateRef cert)
814{
815 CFStringRef server_cert_summary = CFSTR("(null)")((CFStringRef) __builtin___CFStringMakeConstantString ("" "(null)"
""))
;
816
817#if CURL_BUILD_IOS0
818 /* iOS: There's only one way to do this. */
819 server_cert_summary = SecCertificateCopySubjectSummary(cert);
820#else
821#if CURL_BUILD_MAC_10_71080 >= 1070
822 /* Lion & later: Get the long description if we can. */
823 if(SecCertificateCopyLongDescription != NULL((void*)0))
824 server_cert_summary =
825 SecCertificateCopyLongDescription(NULL((void*)0), cert, NULL((void*)0));
826 else
827#endif /* CURL_BUILD_MAC_10_7 */
828#if CURL_BUILD_MAC_10_61080 >= 1060
829 /* Snow Leopard: Get the certificate summary. */
830 if(SecCertificateCopySubjectSummary != NULL((void*)0))
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_61080 <= 1060
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: */
843static 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((void*)0);
850 SecCertificateRef cert = NULL((void*)0);
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((void*)0),
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((void*)0), 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
882static OSStatus CopyIdentityWithLabel(char *label,
883 SecIdentityRef *out_cert_and_key)
884{
885 OSStatus status = errSecItemNotFound;
886
887#if CURL_BUILD_MAC_10_71080 >= 1070 || CURL_BUILD_IOS0
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((void*)0) && kSecClassIdentity != NULL((void*)0)) {
892 CFTypeRef keys[4];
893 CFTypeRef values[4];
894 CFDictionaryRef query_dict;
895 CFStringRef label_cf = CFStringCreateWithCString(NULL((void*)0), 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(false0, label_cf);
907 keys[3] = kSecMatchPolicy;
908 query_dict = CFDictionaryCreate(NULL((void*)0), (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_61080 <= 1060
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_61080 <= 1060
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
933static 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((void*)0),
939 (const UInt8 *)cPath, strlen(cPath), false0);
940 CFStringRef password = cPassword ? CFStringCreateWithCString(NULL((void*)0),
941 cPassword, kCFStringEncodingUTF8) : NULL((void*)0);
942 CFDataRef pkcs_data = NULL((void*)0);
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_71080 >= 1070 || CURL_BUILD_IOS0
948 if(CFURLCreateDataAndPropertiesFromResource(NULL((void*)0), pkcs_url, &pkcs_data,
949 NULL((void*)0), NULL((void*)0), &status)) {
950 const void *cKeys[] = {kSecImportExportPassphrase};
951 const void *cValues[] = {password};
952 CFDictionaryRef options = CFDictionaryCreate(NULL((void*)0), cKeys, cValues,
953 password ? 1L : 0L, NULL((void*)0), NULL((void*)0));
954 CFArrayRef items = NULL((void*)0);
955
956 /* Here we go: */
957 status = SecPKCS12Import(pkcs_data, options, &items);
958 if(status == noErr) {
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 CFRelease(items);
967 }
968 CFRelease(options);
969 CFRelease(pkcs_data);
970 }
971#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
972 if(password)
973 CFRelease(password);
974 CFRelease(pkcs_url);
975 return status;
976}
977
978/* This code was borrowed from nss.c, with some modifications:
979 * Determine whether the nickname passed in is a filename that needs to
980 * be loaded as a PEM or a regular NSS nickname.
981 *
982 * returns 1 for a file
983 * returns 0 for not a file
984 */
985CF_INLINEstatic __inline__ __attribute__((always_inline)) bool_Bool is_file(const char *filename)
986{
987 struct_statstruct stat st;
988
989 if(filename == NULL((void*)0))
990 return false0;
991
992 if(stat(filename, &st) == 0)
993 return S_ISREG(st.st_mode)(((st.st_mode) & 0170000) == 0100000);
994 return false0;
995}
996
997static CURLcode darwinssl_connect_step1(struct connectdata *conn,
998 int sockindex)
999{
1000 struct SessionHandle *data = conn->data;
1001 curl_socket_t sockfd = conn->sock[sockindex];
1002 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1003#ifdef ENABLE_IPV61
1004 struct in6_addr addr;
1005#else
1006 struct in_addr addr;
1007#endif /* ENABLE_IPV6 */
1008 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1009 SSLCipherSuite *all_ciphers = NULL((void*)0), *allowed_ciphers = NULL((void*)0);
1010 char *ssl_sessionid;
1011 size_t ssl_sessionid_len;
1012 OSStatus err = noErr;
1013#if CURL_BUILD_MAC1
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_81080 >= 1080 || CURL_BUILD_IOS0
1020 if(SSLCreateContext != NULL((void*)0)) { /* use the newer API if avaialble */
1021 if(connssl->ssl_ctx)
1022 CFRelease(connssl->ssl_ctx);
1023 connssl->ssl_ctx = SSLCreateContext(NULL((void*)0), kSSLClientSide, kSSLStreamType);
1024 if(!connssl->ssl_ctx) {
1025 failfCurl_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_81080 <= 1080
1032 if(connssl->ssl_ctx)
1033 (void)SSLDisposeContext(connssl->ssl_ctx);
1034 err = SSLNewContext(false0, &(connssl->ssl_ctx));
1035 if(err != noErr) {
1036 failfCurl_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(false0, &(connssl->ssl_ctx));
1045 if(err != noErr) {
1046 failfCurl_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_81080 >= 1080 || CURL_BUILD_IOS0
1054 if(SSLSetProtocolVersionMax != NULL((void*)0)) {
1055 switch(data->set.ssl.version) {
1056 case CURL_SSLVERSION_DEFAULT: default:
1057 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1058 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1059 break;
1060 case CURL_SSLVERSION_TLSv1:
1061 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1062 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1063 break;
1064 case CURL_SSLVERSION_TLSv1_0:
1065 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
1066 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
1067 break;
1068 case CURL_SSLVERSION_TLSv1_1:
1069 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
1070 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
1071 break;
1072 case CURL_SSLVERSION_TLSv1_2:
1073 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
1074 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
1075 break;
1076 case CURL_SSLVERSION_SSLv3:
1077 (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
1078 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
1079 break;
1080 case CURL_SSLVERSION_SSLv2:
1081 err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
1082 if(err != noErr) {
1083 failfCurl_failf(data, "Your version of the OS does not support SSLv2");
1084 return CURLE_SSL_CONNECT_ERROR;
1085 }
1086 (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
1087 }
1088 }
1089 else {
1090#if CURL_SUPPORT_MAC_10_81080 <= 1080
1091 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1092 kSSLProtocolAll,
1093 false0);
1094 switch (data->set.ssl.version) {
1095 case CURL_SSLVERSION_DEFAULT: default:
1096 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1097 kSSLProtocol3,
1098 true1);
1099 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1100 kTLSProtocol1,
1101 true1);
1102 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1103 kTLSProtocol11,
1104 true1);
1105 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1106 kTLSProtocol12,
1107 true1);
1108 break;
1109 case CURL_SSLVERSION_TLSv1:
1110 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1111 kTLSProtocol1,
1112 true1);
1113 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1114 kTLSProtocol11,
1115 true1);
1116 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1117 kTLSProtocol12,
1118 true1);
1119 break;
1120 case CURL_SSLVERSION_TLSv1_0:
1121 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1122 kTLSProtocol1,
1123 true1);
1124 break;
1125 case CURL_SSLVERSION_TLSv1_1:
1126 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1127 kTLSProtocol11,
1128 true1);
1129 break;
1130 case CURL_SSLVERSION_TLSv1_2:
1131 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1132 kTLSProtocol12,
1133 true1);
1134 break;
1135 case CURL_SSLVERSION_SSLv3:
1136 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1137 kSSLProtocol3,
1138 true1);
1139 break;
1140 case CURL_SSLVERSION_SSLv2:
1141 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1142 kSSLProtocol2,
1143 true1);
1144 if(err != noErr) {
1145 failfCurl_failf(data, "Your version of the OS does not support SSLv2");
1146 return CURLE_SSL_CONNECT_ERROR;
1147 }
1148 break;
1149 }
1150#endif /* CURL_SUPPORT_MAC_10_8 */
1151 }
1152#else
1153 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false0);
1154 switch(data->set.ssl.version) {
1155 default:
1156 case CURL_SSLVERSION_DEFAULT:
1157 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1158 kSSLProtocol3,
1159 true1);
1160 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1161 kTLSProtocol1,
1162 true1);
1163 break;
1164 case CURL_SSLVERSION_TLSv1:
1165 case CURL_SSLVERSION_TLSv1_0:
1166 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1167 kTLSProtocol1,
1168 true1);
1169 break;
1170 case CURL_SSLVERSION_TLSv1_1:
1171 failfCurl_failf(data, "Your version of the OS does not support TLSv1.1");
1172 return CURLE_SSL_CONNECT_ERROR;
1173 case CURL_SSLVERSION_TLSv1_2:
1174 failfCurl_failf(data, "Your version of the OS does not support TLSv1.2");
1175 return CURLE_SSL_CONNECT_ERROR;
1176 case CURL_SSLVERSION_SSLv2:
1177 err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1178 kSSLProtocol2,
1179 true1);
1180 if(err != noErr) {
1181 failfCurl_failf(data, "Your version of the OS does not support SSLv2");
1182 return CURLE_SSL_CONNECT_ERROR;
1183 }
1184 break;
1185 case CURL_SSLVERSION_SSLv3:
1186 (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
1187 kSSLProtocol3,
1188 true1);
1189 break;
1190 }
1191#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1192
1193 if(data->set.str[STRING_KEY]) {
1194 infofCurl_infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1195 "Transport. The private key must be in the Keychain.\n");
1196 }
1197
1198 if(data->set.str[STRING_CERT]) {
1199 SecIdentityRef cert_and_key = NULL((void*)0);
1200 bool_Bool is_cert_file = is_file(data->set.str[STRING_CERT]);
1201
1202 /* User wants to authenticate with a client cert. Look for it:
1203 If we detect that this is a file on disk, then let's load it.
1204 Otherwise, assume that the user wants to use an identity loaded
1205 from the Keychain. */
1206 if(is_cert_file) {
1207 if(!data->set.str[STRING_CERT_TYPE])
1208 infofCurl_infof(data, "WARNING: SSL: Certificate type not set, assuming "
1209 "PKCS#12 format.\n");
1210 else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12",
1211 strlen(data->set.str[STRING_CERT_TYPE])) != 0)
1212 infofCurl_infof(data, "WARNING: SSL: The Security framework only supports "
1213 "loading identities that are in PKCS#12 format.\n");
1214
1215 err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT],
1216 data->set.str[STRING_KEY_PASSWD], &cert_and_key);
1217 }
1218 else
1219 err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
1220
1221 if(err == noErr) {
1222 SecCertificateRef cert = NULL((void*)0);
1223 CFTypeRef certs_c[1];
1224 CFArrayRef certs;
1225
1226 /* If we found one, print it out: */
1227 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1228 if(err == noErr) {
1229 CFStringRef cert_summary = CopyCertSubject(cert);
1230 char cert_summary_c[128];
1231
1232 if(cert_summary) {
1233 memset(cert_summary_c, 0, 128)((__builtin_object_size (cert_summary_c, 0) != (size_t) -1) ?
__builtin___memset_chk (cert_summary_c, 0, 128, __builtin_object_size
(cert_summary_c, 0)) : __inline_memset_chk (cert_summary_c, 0
, 128))
;
1234 if(CFStringGetCString(cert_summary,
1235 cert_summary_c,
1236 128,
1237 kCFStringEncodingUTF8)) {
1238 infofCurl_infof(data, "Client certificate: %s\n", cert_summary_c);
1239 }
1240 CFRelease(cert_summary);
1241 CFRelease(cert);
1242 }
1243 }
1244 certs_c[0] = cert_and_key;
1245 certs = CFArrayCreate(NULL((void*)0), (const void **)certs_c, 1L,
1246 &kCFTypeArrayCallBacks);
1247 err = SSLSetCertificate(connssl->ssl_ctx, certs);
1248 if(certs)
1249 CFRelease(certs);
1250 if(err != noErr) {
1251 failfCurl_failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1252 return CURLE_SSL_CERTPROBLEM;
1253 }
1254 CFRelease(cert_and_key);
1255 }
1256 else {
1257 switch(err) {
1258 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1259 failfCurl_failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1260 "and its private key.", data->set.str[STRING_CERT]);
1261 break;
1262 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1263 failfCurl_failf(data, "SSL: Couldn't make sense of the data in the "
1264 "certificate \"%s\" and its private key.",
1265 data->set.str[STRING_CERT]);
1266 break;
1267 case -25260: /* errSecPassphraseRequired */
1268 failfCurl_failf(data, "SSL The certificate \"%s\" requires a password.",
1269 data->set.str[STRING_CERT]);
1270 break;
1271 case errSecItemNotFound:
1272 failfCurl_failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1273 "key in the Keychain.", data->set.str[STRING_CERT]);
1274 break;
1275 default:
1276 failfCurl_failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1277 "key: OSStatus %d", data->set.str[STRING_CERT], err);
1278 break;
1279 }
1280 return CURLE_SSL_CERTPROBLEM;
1281 }
1282 }
1283
1284 /* SSL always tries to verify the peer, this only says whether it should
1285 * fail to connect if the verification fails, or if it should continue
1286 * anyway. In the latter case the result of the verification is checked with
1287 * SSL_get_verify_result() below. */
1288#if CURL_BUILD_MAC_10_61080 >= 1060 || CURL_BUILD_IOS0
1289 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1290 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1291 works, it doesn't work as expected under Snow Leopard or Lion.
1292 So we need to call SSLSetEnableCertVerify() on those older cats in order
1293 to disable certificate validation if the user turned that off.
1294 (SecureTransport will always validate the certificate chain by
1295 default.) */
1296 /* (Note: Darwin 12.x.x is Mountain Lion.) */
1297#if CURL_BUILD_MAC1
1298 if(SSLSetSessionOption != NULL((void*)0) && darwinver_maj >= 12) {
1299#else
1300 if(SSLSetSessionOption != NULL((void*)0)) {
1301#endif /* CURL_BUILD_MAC */
1302 bool_Bool break_on_auth = !data->set.ssl.verifypeer ||
1303 data->set.str[STRING_SSL_CAFILE];
1304 err = SSLSetSessionOption(connssl->ssl_ctx,
1305 kSSLSessionOptionBreakOnServerAuth,
1306 break_on_auth);
1307 if(err != noErr) {
1308 failfCurl_failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1309 return CURLE_SSL_CONNECT_ERROR;
1310 }
1311 }
1312 else {
1313#if CURL_SUPPORT_MAC_10_81080 <= 1080
1314 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1315 data->set.ssl.verifypeer?true1:false0);
1316 if(err != noErr) {
1317 failfCurl_failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1318 return CURLE_SSL_CONNECT_ERROR;
1319 }
1320#endif /* CURL_SUPPORT_MAC_10_8 */
1321 }
1322#else
1323 err = SSLSetEnableCertVerify(connssl->ssl_ctx,
1324 data->set.ssl.verifypeer?true1:false0);
1325 if(err != noErr) {
1326 failfCurl_failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1327 return CURLE_SSL_CONNECT_ERROR;
1328 }
1329#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1330
1331 if(data->set.str[STRING_SSL_CAFILE]) {
1332 bool_Bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]);
1333 if (!is_cert_file) {
1334 failfCurl_failf(data, "SSL: can't load CA certificate file %s",
1335 data->set.str[STRING_SSL_CAFILE]);
1336 return CURLE_SSL_CACERT_BADFILE;
1337 }
1338 if (!data->set.ssl.verifypeer) {
1339 failfCurl_failf(data, "SSL: CA certificate set, but certificate verification "
1340 "is disabled");
1341 return CURLE_SSL_CONNECT_ERROR;
1342 }
1343 }
1344
1345 /* Configure hostname check. SNI is used if available.
1346 * Both hostname check and SNI require SSLSetPeerDomainName().
1347 * Also: the verifyhost setting influences SNI usage */
1348 if(data->set.ssl.verifyhost) {
1349 err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
1350 strlen(conn->host.name));
1351
1352 if(err != noErr) {
1353 infofCurl_infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1354 err);
1355 }
1356
1357 if((Curl_inet_pton(AF_INET, conn->host.name, &addr)inet_pton(2,conn->host.name,&addr))
1358 #ifdef ENABLE_IPV61
1359 || (Curl_inet_pton(AF_INET6, conn->host.name, &addr)inet_pton(30,conn->host.name,&addr))
1360 #endif
1361 ) {
1362 infofCurl_infof(data, "WARNING: using IP address, SNI is being disabled by "
1363 "the OS.\n");
1364 }
1365 }
1366
1367 /* Disable cipher suites that ST supports but are not safe. These ciphers
1368 are unlikely to be used in any case since ST gives other ciphers a much
1369 higher priority, but it's probably better that we not connect at all than
1370 to give the user a false sense of security if the server only supports
1371 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1372 (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
1373 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite))Curl_cmalloc(all_ciphers_count*sizeof(SSLCipherSuite));
1374 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite))Curl_cmalloc(all_ciphers_count*sizeof(SSLCipherSuite));
1375 if(all_ciphers && allowed_ciphers &&
1376 SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
1377 &all_ciphers_count) == noErr) {
1378 for(i = 0UL ; i < all_ciphers_count ; i++) {
1379#if CURL_BUILD_MAC1
1380 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1381 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1382 Work around the problem here by disabling those ciphers if we are
1383 running in an affected version of OS X. */
1384 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1385 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1386 continue;
1387 }
1388#endif /* CURL_BUILD_MAC */
1389 switch(all_ciphers[i]) {
1390 /* Disable NULL ciphersuites: */
1391 case SSL_NULL_WITH_NULL_NULL:
1392 case SSL_RSA_WITH_NULL_MD5:
1393 case SSL_RSA_WITH_NULL_SHA:
1394 case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1395 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1396 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1397 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1398 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1399 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1400 case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1401 case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1402 case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1403 case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1404 case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1405 case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1406 case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1407 case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1408 case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1409 /* Disable anonymous ciphersuites: */
1410 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1411 case SSL_DH_anon_WITH_RC4_128_MD5:
1412 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1413 case SSL_DH_anon_WITH_DES_CBC_SHA:
1414 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1415 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1416 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1417 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1418 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1419 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1420 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1421 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1422 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1423 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1424 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1425 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1426 /* Disable weak key ciphersuites: */
1427 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1428 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1429 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1430 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1431 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1432 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1433 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1434 case SSL_RSA_WITH_DES_CBC_SHA:
1435 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1436 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1437 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1438 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1439 /* Disable IDEA: */
1440 case SSL_RSA_WITH_IDEA_CBC_SHA:
1441 case SSL_RSA_WITH_IDEA_CBC_MD5:
1442 break;
1443 default: /* enable everything else */
1444 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1445 break;
1446 }
1447 }
1448 err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
1449 allowed_ciphers_count);
1450 if(err != noErr) {
1451 failfCurl_failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1452 return CURLE_SSL_CONNECT_ERROR;
1453 }
1454 }
1455 else {
1456 Curl_safefree(all_ciphers)do {if((all_ciphers)) {Curl_cfree((all_ciphers)); (all_ciphers
) = ((void*)0);}} while(0)
;
1457 Curl_safefree(allowed_ciphers)do {if((allowed_ciphers)) {Curl_cfree((allowed_ciphers)); (allowed_ciphers
) = ((void*)0);}} while(0)
;
1458 failfCurl_failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1459 return CURLE_OUT_OF_MEMORY;
1460 }
1461 Curl_safefree(all_ciphers)do {if((all_ciphers)) {Curl_cfree((all_ciphers)); (all_ciphers
) = ((void*)0);}} while(0)
;
1462 Curl_safefree(allowed_ciphers)do {if((allowed_ciphers)) {Curl_cfree((allowed_ciphers)); (allowed_ciphers
) = ((void*)0);}} while(0)
;
1463
1464#if CURL_BUILD_MAC_10_91080 >= 1090 || CURL_BUILD_IOS_70
1465 /* We want to enable 1/n-1 when using a CBC cipher unless the user
1466 specifically doesn't want us doing that: */
1467 if(SSLSetSessionOption != NULL((void*)0))
1468 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1469 !data->set.ssl_enable_beast);
1470#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1471
1472 /* Check if there's a cached ID we can/should use here! */
1473 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1474 &ssl_sessionid_len)) {
1475 /* we got a session id, use it! */
1476 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1477 if(err != noErr) {
1478 failfCurl_failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1479 return CURLE_SSL_CONNECT_ERROR;
1480 }
1481 /* Informational message */
1482 infofCurl_infof(data, "SSL re-using session ID\n");
1483 }
1484 /* If there isn't one, then let's make one up! This has to be done prior
1485 to starting the handshake. */
1486 else {
1487 CURLcode retcode;
1488
1489 ssl_sessionid = malloc(256*sizeof(char))Curl_cmalloc(256*sizeof(char));
1490 ssl_sessionid_len = snprintfcurl_msnprintf(ssl_sessionid, 256, "curl:%s:%hu",
1491 conn->host.name, conn->remote_port);
1492 err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1493 if(err != noErr) {
1494 failfCurl_failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1495 return CURLE_SSL_CONNECT_ERROR;
1496 }
1497 retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
1498 if(retcode!= CURLE_OK) {
1499 failfCurl_failf(data, "failed to store ssl session");
1500 return retcode;
1501 }
1502 }
1503
1504 err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
1505 if(err != noErr) {
1506 failfCurl_failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1507 return CURLE_SSL_CONNECT_ERROR;
1508 }
1509
1510 /* pass the raw socket into the SSL layers */
1511 /* We need to store the FD in a constant memory address, because
1512 * SSLSetConnection() will not copy that address. I've found that
1513 * conn->sock[sockindex] may change on its own. */
1514 connssl->ssl_sockfd = sockfd;
1515 err = SSLSetConnection(connssl->ssl_ctx, connssl);
1516 if(err != noErr) {
1517 failfCurl_failf(data, "SSL: SSLSetConnection() failed: %d", err);
1518 return CURLE_SSL_CONNECT_ERROR;
1519 }
1520
1521 connssl->connecting_state = ssl_connect_2;
1522 return CURLE_OK;
1523}
1524
1525static int pem_to_der(const char *in, unsigned char **out, size_t *outlen)
1526{
1527 char *sep, *start, *end;
1528 int i, j, err;
1529 size_t len;
1530 unsigned char *b64;
1531
1532 /* Jump through the separators in the first line. */
1533 sep = strstr(in, "-----");
1534 if (sep == NULL((void*)0))
1535 return -1;
1536 sep = strstr(sep + 1, "-----");
1537 if (sep == NULL((void*)0))
1538 return -1;
1539
1540 start = sep + 5;
1541
1542 /* Find beginning of last line separator. */
1543 end = strstr(start, "-----");
1544 if (end == NULL((void*)0))
1545 return -1;
1546
1547 len = end - start;
1548 *out = malloc(len)Curl_cmalloc(len);
1549 if (!*out)
1550 return -1;
1551
1552 b64 = malloc(len + 1)Curl_cmalloc(len + 1);
1553 if (!b64) {
1554 free(*out)Curl_cfree(*out);
1555 return -1;
1556 }
1557
1558 /* Create base64 string without linefeeds. */
1559 for (i = 0, j = 0; i < len; i++) {
1560 if (start[i] != '\r' && start[i] != '\n')
1561 b64[j++] = start[i];
1562 }
1563 b64[j] = '\0';
1564
1565 err = (int)Curl_base64_decode((const char *)b64, out, outlen);
1566 free(b64)Curl_cfree(b64);
1567 if (err) {
1568 free(*out)Curl_cfree(*out);
1569 return -1;
1570 }
1571
1572 return 0;
1573}
1574
1575static int read_cert(const char *file, unsigned char **out, size_t *outlen)
1576{
1577 int fd, ret, n, len = 0, cap = 512;
1578 size_t derlen;
1579 unsigned char buf[cap], *data, *der;
1580
1581 fd = open(file, 0);
1582 if (fd < 0)
1583 return -1;
1584
1585 data = malloc(cap)Curl_cmalloc(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)Curl_cfree(data);
1596 return -1;
1597 } else if (n == 0) {
1598 close(fd);
1599 break;
1600 }
1601
1602 if (len + n >= cap) {
1603 cap *= 2;
1604 data = realloc(data, cap)Curl_crealloc(data, cap);
1605 if (!data) {
1606 close(fd);
1607 return -1;
1608 }
1609 }
1610
1611 memcpy(data + len, buf, n)((__builtin_object_size (data + len, 0) != (size_t) -1) ? __builtin___memcpy_chk
(data + len, buf, n, __builtin_object_size (data + len, 0)) :
__inline_memcpy_chk (data + len, buf, n))
;
1612 len += n;
1613 }
1614 data[len] = '\0';
1615
1616 /*
1617 * Check if the certificate is in PEM format, and convert it to DER. If this
1618 * fails, we assume the certificate is in DER format.
1619 */
1620 if (pem_to_der((const char *)data, &der, &derlen) == 0) {
1621 free(data)Curl_cfree(data);
1622 data = der;
1623 len = derlen;
1624 }
1625
1626 *out = data;
1627 *outlen = len;
1628
1629 return 0;
1630}
1631
1632static int sslerr_to_curlerr(struct SessionHandle *data, int err)
1633{
1634 switch(err) {
1635 case errSSLXCertChainInvalid:
1636 failfCurl_failf(data, "SSL certificate problem: Invalid certificate chain");
1637 return CURLE_SSL_CACERT;
1638 case errSSLUnknownRootCert:
1639 failfCurl_failf(data, "SSL certificate problem: Untrusted root certificate");
1640 return CURLE_SSL_CACERT;
1641 case errSSLNoRootCert:
1642 failfCurl_failf(data, "SSL certificate problem: No root certificate");
1643 return CURLE_SSL_CACERT;
1644 case errSSLCertExpired:
1645 failfCurl_failf(data, "SSL certificate problem: Certificate chain had an "
1646 "expired certificate");
1647 return CURLE_SSL_CACERT;
1648 case errSSLBadCert:
1649 failfCurl_failf(data, "SSL certificate problem: Couldn't understand the server "
1650 "certificate format");
1651 return CURLE_SSL_CONNECT_ERROR;
1652 case errSSLHostNameMismatch:
1653 failfCurl_failf(data, "SSL certificate peer hostname mismatch");
1654 return CURLE_PEER_FAILED_VERIFICATION;
1655 default:
1656 failfCurl_failf(data, "SSL unexpected certificate error %d", err);
1657 return CURLE_SSL_CACERT;
1658 }
1659}
1660
1661static int verify_cert(const char *cafile, struct SessionHandle *data,
1662 SSLContextRef ctx)
1663{
1664 unsigned char *certbuf;
1665 size_t buflen;
1666 if (read_cert(cafile, &certbuf, &buflen) < 0) {
1667 failfCurl_failf(data, "SSL: failed to read or invalid CA certificate");
1668 return CURLE_SSL_CACERT;
1669 }
1670
1671 CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, certbuf, buflen);
1672 free(certbuf)Curl_cfree(certbuf);
1673 if (!certdata) {
1674 failfCurl_failf(data, "SSL: failed to allocate array for CA certificate");
1675 return CURLE_OUT_OF_MEMORY;
1676 }
1677
1678 SecCertificateRef cacert = SecCertificateCreateWithData(kCFAllocatorDefault,
1679 certdata);
1680 CFRelease(certdata);
1681 if (!cacert) {
1682 failfCurl_failf(data, "SSL: failed to create SecCertificate from CA certificate");
1683 return CURLE_SSL_CACERT;
1684 }
1685
1686 SecTrustRef trust;
1687 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
1688 if (trust == NULL((void*)0)) {
1689 failfCurl_failf(data, "SSL: error getting certificate chain");
1690 return CURLE_OUT_OF_MEMORY;
1691 } else if (ret != noErr) {
1692 return sslerr_to_curlerr(data, ret);
1693 }
1694
1695 CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
1696 &kCFTypeArrayCallBacks);
1697 CFArrayAppendValue(array, cacert);
1698 CFRelease(cacert);
1699
1700 ret = SecTrustSetAnchorCertificates(trust, array);
1701 if (ret != noErr) {
1702 CFRelease(trust);
1703 return sslerr_to_curlerr(data, ret);
1704 }
1705
1706 SecTrustResultType trust_eval = 0;
1707 ret = SecTrustEvaluate(trust, &trust_eval);
1708 CFRelease(array);
1709 CFRelease(trust);
1710 if (ret != noErr) {
1711 return sslerr_to_curlerr(data, ret);
1712 }
1713
1714 switch (trust_eval) {
1715 case kSecTrustResultUnspecified:
1716 case kSecTrustResultProceed:
1717 infofCurl_infof(data, "SSL: certificate verification succeeded (result: %d)",
1718 trust_eval);
1719 return CURLE_OK;
1720
1721 case kSecTrustResultRecoverableTrustFailure:
1722 case kSecTrustResultDeny:
1723 default:
1724 failfCurl_failf(data, "SSL: certificate verification failed (result: %d)",
1725 trust_eval);
1726 return CURLE_PEER_FAILED_VERIFICATION;
1727 }
1728}
1729
1730static CURLcode
1731darwinssl_connect_step2(struct connectdata *conn, int sockindex)
1732{
1733 struct SessionHandle *data = conn->data;
1734 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1735 OSStatus err;
1736 SSLCipherSuite cipher;
1737 SSLProtocol protocol = 0;
1738
1739 DEBUGASSERT(ssl_connect_2 == connssl->connecting_statedo { } while(0)
1740 || ssl_connect_2_reading == connssl->connecting_statedo { } while(0)
1741 || ssl_connect_2_writing == connssl->connecting_state)do { } while(0);
1742
1743 /* Here goes nothing: */
1744 err = SSLHandshake(connssl->ssl_ctx);
1745
1746 if(err != noErr) {
1747 switch (err) {
1748 case errSSLWouldBlock: /* they're not done with us yet */
1749 connssl->connecting_state = connssl->ssl_direction ?
1750 ssl_connect_2_writing : ssl_connect_2_reading;
1751 return CURLE_OK;
1752
1753 /* The below is errSSLServerAuthCompleted; it's not defined in
1754 Leopard's headers */
1755 case -9841:
1756 if(data->set.str[STRING_SSL_CAFILE]) {
1757 int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data,
1758 connssl->ssl_ctx);
1759 if (res != CURLE_OK)
1760 return res;
1761 }
1762 /* the documentation says we need to call SSLHandshake() again */
1763 return darwinssl_connect_step2(conn, sockindex);
1764
1765 /* These are all certificate problems with the server: */
1766 case errSSLXCertChainInvalid:
1767 failfCurl_failf(data, "SSL certificate problem: Invalid certificate chain");
1768 return CURLE_SSL_CACERT;
1769 case errSSLUnknownRootCert:
1770 failfCurl_failf(data, "SSL certificate problem: Untrusted root certificate");
1771 return CURLE_SSL_CACERT;
1772 case errSSLNoRootCert:
1773 failfCurl_failf(data, "SSL certificate problem: No root certificate");
1774 return CURLE_SSL_CACERT;
1775 case errSSLCertExpired:
1776 failfCurl_failf(data, "SSL certificate problem: Certificate chain had an "
1777 "expired certificate");
1778 return CURLE_SSL_CACERT;
1779 case errSSLBadCert:
1780 failfCurl_failf(data, "SSL certificate problem: Couldn't understand the server "
1781 "certificate format");
1782 return CURLE_SSL_CONNECT_ERROR;
1783
1784 /* These are all certificate problems with the client: */
1785 case errSecAuthFailed:
1786 failfCurl_failf(data, "SSL authentication failed");
1787 return CURLE_SSL_CONNECT_ERROR;
1788 case errSSLPeerHandshakeFail:
1789 failfCurl_failf(data, "SSL peer handshake failed, the server most likely "
1790 "requires a client certificate to connect");
1791 return CURLE_SSL_CONNECT_ERROR;
1792 case errSSLPeerUnknownCA:
1793 failfCurl_failf(data, "SSL server rejected the client certificate due to "
1794 "the certificate being signed by an unknown certificate "
1795 "authority");
1796 return CURLE_SSL_CONNECT_ERROR;
1797
1798 /* This error is raised if the server's cert didn't match the server's
1799 host name: */
1800 case errSSLHostNameMismatch:
1801 failfCurl_failf(data, "SSL certificate peer verification failed, the "
1802 "certificate did not match \"%s\"\n", conn->host.dispname);
1803 return CURLE_PEER_FAILED_VERIFICATION;
1804
1805 /* Generic handshake errors: */
1806 case errSSLConnectionRefused:
1807 failfCurl_failf(data, "Server dropped the connection during the SSL handshake");
1808 return CURLE_SSL_CONNECT_ERROR;
1809 case errSSLClosedAbort:
1810 failfCurl_failf(data, "Server aborted the SSL handshake");
1811 return CURLE_SSL_CONNECT_ERROR;
1812 case errSSLNegotiation:
1813 failfCurl_failf(data, "Could not negotiate an SSL cipher suite with the server");
1814 return CURLE_SSL_CONNECT_ERROR;
1815 /* Sometimes paramErr happens with buggy ciphers: */
1816 case paramErr-50: case errSSLInternal:
1817 failfCurl_failf(data, "Internal SSL engine error encountered during the "
1818 "SSL handshake");
1819 return CURLE_SSL_CONNECT_ERROR;
1820 case errSSLFatalAlert:
1821 failfCurl_failf(data, "Fatal SSL engine error encountered during the SSL "
1822 "handshake");
1823 return CURLE_SSL_CONNECT_ERROR;
1824 default:
1825 failfCurl_failf(data, "Unknown SSL protocol error in connection to %s:%d",
1826 conn->host.name, err);
1827 return CURLE_SSL_CONNECT_ERROR;
1828 }
1829 }
1830 else {
1831 /* we have been connected fine, we're not waiting for anything else. */
1832 connssl->connecting_state = ssl_connect_3;
1833
1834 /* Informational message */
1835 (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
1836 (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
1837 switch (protocol) {
1838 case kSSLProtocol2:
1839 infofCurl_infof(data, "SSL 2.0 connection using %s\n",
1840 SSLCipherNameForNumber(cipher));
1841 break;
1842 case kSSLProtocol3:
1843 infofCurl_infof(data, "SSL 3.0 connection using %s\n",
1844 SSLCipherNameForNumber(cipher));
1845 break;
1846 case kTLSProtocol1:
1847 infofCurl_infof(data, "TLS 1.0 connection using %s\n",
1848 TLSCipherNameForNumber(cipher));
1849 break;
1850#if CURL_BUILD_MAC_10_81080 >= 1080 || CURL_BUILD_IOS0
1851 case kTLSProtocol11:
1852 infofCurl_infof(data, "TLS 1.1 connection using %s\n",
1853 TLSCipherNameForNumber(cipher));
1854 break;
1855 case kTLSProtocol12:
1856 infofCurl_infof(data, "TLS 1.2 connection using %s\n",
1857 TLSCipherNameForNumber(cipher));
1858 break;
1859#endif
1860 default:
1861 infofCurl_infof(data, "Unknown protocol connection\n");
1862 break;
1863 }
1864
1865 return CURLE_OK;
1866 }
1867}
1868
1869static CURLcode
1870darwinssl_connect_step3(struct connectdata *conn,
1871 int sockindex)
1872{
1873 struct SessionHandle *data = conn->data;
1874 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1875 CFStringRef server_cert_summary;
1876 char server_cert_summary_c[128];
1877 CFArrayRef server_certs = NULL((void*)0);
1878 SecCertificateRef server_cert;
1879 OSStatus err;
1880 CFIndex i, count;
1881 SecTrustRef trust = NULL((void*)0);
1882
1883 /* There is no step 3!
1884 * Well, okay, if verbose mode is on, let's print the details of the
1885 * server certificates. */
1886#if CURL_BUILD_MAC_10_71080 >= 1070 || CURL_BUILD_IOS0
1887#if CURL_BUILD_IOS0
1888#pragma unused(server_certs)
1889 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1890 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1891 a null trust, so be on guard for that: */
1892 if(err == noErr && trust) {
1893 count = SecTrustGetCertificateCount(trust);
1894 for(i = 0L ; i < count ; i++) {
1895 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1896 server_cert_summary = CopyCertSubject(server_cert);
1897 memset(server_cert_summary_c, 0, 128)((__builtin_object_size (server_cert_summary_c, 0) != (size_t
) -1) ? __builtin___memset_chk (server_cert_summary_c, 0, 128
, __builtin_object_size (server_cert_summary_c, 0)) : __inline_memset_chk
(server_cert_summary_c, 0, 128))
;
1898 if(CFStringGetCString(server_cert_summary,
1899 server_cert_summary_c,
1900 128,
1901 kCFStringEncodingUTF8)) {
1902 infofCurl_infof(data, "Server certificate: %s\n", server_cert_summary_c);
1903 }
1904 CFRelease(server_cert_summary);
1905 }
1906 CFRelease(trust);
1907 }
1908#else
1909 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
1910 The function SecTrustGetCertificateAtIndex() is officially present
1911 in Lion, but it is unfortunately also present in Snow Leopard as
1912 private API and doesn't work as expected. So we have to look for
1913 a different symbol to make sure this code is only executed under
1914 Lion or later. */
1915 if(SecTrustEvaluateAsync != NULL((void*)0)) {
1916#pragma unused(server_certs)
1917 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
1918 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
1919 a null trust, so be on guard for that: */
1920 if(err == noErr && trust) {
1921 count = SecTrustGetCertificateCount(trust);
1922 for(i = 0L ; i < count ; i++) {
1923 server_cert = SecTrustGetCertificateAtIndex(trust, i);
1924 server_cert_summary = CopyCertSubject(server_cert);
1925 memset(server_cert_summary_c, 0, 128)((__builtin_object_size (server_cert_summary_c, 0) != (size_t
) -1) ? __builtin___memset_chk (server_cert_summary_c, 0, 128
, __builtin_object_size (server_cert_summary_c, 0)) : __inline_memset_chk
(server_cert_summary_c, 0, 128))
;
1926 if(CFStringGetCString(server_cert_summary,
1927 server_cert_summary_c,
1928 128,
1929 kCFStringEncodingUTF8)) {
1930 infofCurl_infof(data, "Server certificate: %s\n", server_cert_summary_c);
1931 }
1932 CFRelease(server_cert_summary);
1933 }
1934 CFRelease(trust);
1935 }
1936 }
1937 else {
1938#if CURL_SUPPORT_MAC_10_81080 <= 1080
1939 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1940 /* Just in case SSLCopyPeerCertificates() returns null too... */
1941 if(err == noErr && server_certs) {
1942 count = CFArrayGetCount(server_certs);
1943 for(i = 0L ; i < count ; i++) {
1944 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
1945 i);
1946
1947 server_cert_summary = CopyCertSubject(server_cert);
1948 memset(server_cert_summary_c, 0, 128)((__builtin_object_size (server_cert_summary_c, 0) != (size_t
) -1) ? __builtin___memset_chk (server_cert_summary_c, 0, 128
, __builtin_object_size (server_cert_summary_c, 0)) : __inline_memset_chk
(server_cert_summary_c, 0, 128))
;
1949 if(CFStringGetCString(server_cert_summary,
1950 server_cert_summary_c,
1951 128,
1952 kCFStringEncodingUTF8)) {
1953 infofCurl_infof(data, "Server certificate: %s\n", server_cert_summary_c);
1954 }
1955 CFRelease(server_cert_summary);
1956 }
1957 CFRelease(server_certs);
1958 }
1959#endif /* CURL_SUPPORT_MAC_10_8 */
1960 }
1961#endif /* CURL_BUILD_IOS */
1962#else
1963#pragma unused(trust)
1964 err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
1965 if(err == noErr) {
1966 count = CFArrayGetCount(server_certs);
1967 for(i = 0L ; i < count ; i++) {
1968 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
1969 server_cert_summary = CopyCertSubject(server_cert);
1970 memset(server_cert_summary_c, 0, 128)((__builtin_object_size (server_cert_summary_c, 0) != (size_t
) -1) ? __builtin___memset_chk (server_cert_summary_c, 0, 128
, __builtin_object_size (server_cert_summary_c, 0)) : __inline_memset_chk
(server_cert_summary_c, 0, 128))
;
1971 if(CFStringGetCString(server_cert_summary,
1972 server_cert_summary_c,
1973 128,
1974 kCFStringEncodingUTF8)) {
1975 infofCurl_infof(data, "Server certificate: %s\n", server_cert_summary_c);
1976 }
1977 CFRelease(server_cert_summary);
1978 }
1979 CFRelease(server_certs);
1980 }
1981#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1982
1983 connssl->connecting_state = ssl_connect_done;
1984 return CURLE_OK;
1985}
1986
1987static Curl_recv darwinssl_recv;
1988static Curl_send darwinssl_send;
1989
1990static CURLcode
1991darwinssl_connect_common(struct connectdata *conn,
1992 int sockindex,
1993 bool_Bool nonblocking,
1994 bool_Bool *done)
1995{
1996 CURLcode retcode;
1997 struct SessionHandle *data = conn->data;
1998 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1999 curl_socket_t sockfd = conn->sock[sockindex];
2000 long timeout_ms;
2001 int what;
2002
2003 /* check if the connection has already been established */
2004 if(ssl_connection_complete == connssl->state) {
2005 *done = TRUE1;
2006 return CURLE_OK;
2007 }
2008
2009 if(ssl_connect_1==connssl->connecting_state) {
2010 /* Find out how much more time we're allowed */
2011 timeout_ms = Curl_timeleft(data, NULL((void*)0), TRUE1);
2012
2013 if(timeout_ms < 0) {
2014 /* no need to continue if time already is up */
2015 failfCurl_failf(data, "SSL connection timeout");
2016 return CURLE_OPERATION_TIMEDOUT;
2017 }
2018 retcode = darwinssl_connect_step1(conn, sockindex);
2019 if(retcode)
2020 return retcode;
2021 }
2022
2023 while(ssl_connect_2 == connssl->connecting_state ||
2024 ssl_connect_2_reading == connssl->connecting_state ||
2025 ssl_connect_2_writing == connssl->connecting_state) {
2026
2027 /* check allowed time left */
2028 timeout_ms = Curl_timeleft(data, NULL((void*)0), TRUE1);
2029
2030 if(timeout_ms < 0) {
2031 /* no need to continue if time already is up */
2032 failfCurl_failf(data, "SSL connection timeout");
2033 return CURLE_OPERATION_TIMEDOUT;
2034 }
2035
2036 /* if ssl is expecting something, check if it's available. */
2037 if(connssl->connecting_state == ssl_connect_2_reading
2038 || connssl->connecting_state == ssl_connect_2_writing) {
2039
2040 curl_socket_t writefd = ssl_connect_2_writing ==
2041 connssl->connecting_state?sockfd:CURL_SOCKET_BAD-1;
2042 curl_socket_t readfd = ssl_connect_2_reading ==
2043 connssl->connecting_state?sockfd:CURL_SOCKET_BAD-1;
2044
2045 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms)Curl_socket_check(readfd, -1, writefd, nonblocking?0:timeout_ms
)
;
2046 if(what < 0) {
2047 /* fatal error */
2048 failfCurl_failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO((*__error())));
2049 return CURLE_SSL_CONNECT_ERROR;
2050 }
2051 else if(0 == what) {
2052 if(nonblocking) {
2053 *done = FALSE0;
2054 return CURLE_OK;
2055 }
2056 else {
2057 /* timeout */
2058 failfCurl_failf(data, "SSL connection timeout");
2059 return CURLE_OPERATION_TIMEDOUT;
2060 }
2061 }
2062 /* socket is readable or writable */
2063 }
2064
2065 /* Run transaction, and return to the caller if it failed or if this
2066 * connection is done nonblocking and this loop would execute again. This
2067 * permits the owner of a multi handle to abort a connection attempt
2068 * before step2 has completed while ensuring that a client using select()
2069 * or epoll() will always have a valid fdset to wait on.
2070 */
2071 retcode = darwinssl_connect_step2(conn, sockindex);
2072 if(retcode || (nonblocking &&
2073 (ssl_connect_2 == connssl->connecting_state ||
2074 ssl_connect_2_reading == connssl->connecting_state ||
2075 ssl_connect_2_writing == connssl->connecting_state)))
2076 return retcode;
2077
2078 } /* repeat step2 until all transactions are done. */
2079
2080
2081 if(ssl_connect_3==connssl->connecting_state) {
2082 retcode = darwinssl_connect_step3(conn, sockindex);
2083 if(retcode)
2084 return retcode;
2085 }
2086
2087 if(ssl_connect_done==connssl->connecting_state) {
2088 connssl->state = ssl_connection_complete;
2089 conn->recv[sockindex] = darwinssl_recv;
2090 conn->send[sockindex] = darwinssl_send;
2091 *done = TRUE1;
2092 }
2093 else
2094 *done = FALSE0;
2095
2096 /* Reset our connect state machine */
2097 connssl->connecting_state = ssl_connect_1;
2098
2099 return CURLE_OK;
2100}
2101
2102CURLcode
2103Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
2104 int sockindex,
2105 bool_Bool *done)
2106{
2107 return darwinssl_connect_common(conn, sockindex, TRUE1, done);
2108}
2109
2110CURLcode
2111Curl_darwinssl_connect(struct connectdata *conn,
2112 int sockindex)
2113{
2114 CURLcode retcode;
2115 bool_Bool done = FALSE0;
2116
2117 retcode = darwinssl_connect_common(conn, sockindex, FALSE0, &done);
2118
2119 if(retcode)
2120 return retcode;
2121
2122 DEBUGASSERT(done)do { } while(0);
2123
2124 return CURLE_OK;
2125}
2126
2127void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
2128{
2129 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2130
2131 if(connssl->ssl_ctx) {
2132 (void)SSLClose(connssl->ssl_ctx);
2133#if CURL_BUILD_MAC_10_81080 >= 1080 || CURL_BUILD_IOS0
2134 if(SSLCreateContext != NULL((void*)0))
2135 CFRelease(connssl->ssl_ctx);
2136#if CURL_SUPPORT_MAC_10_81080 <= 1080
2137 else
2138 (void)SSLDisposeContext(connssl->ssl_ctx);
2139#endif /* CURL_SUPPORT_MAC_10_8 */
2140#else
2141 (void)SSLDisposeContext(connssl->ssl_ctx);
2142#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2143 connssl->ssl_ctx = NULL((void*)0);
2144 }
2145 connssl->ssl_sockfd = 0;
2146}
2147
2148void Curl_darwinssl_close_all(struct SessionHandle *data)
2149{
2150 /* SecureTransport doesn't separate sessions from contexts, so... */
2151 (void)data;
2152}
2153
2154int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
2155{
2156 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2157 struct SessionHandle *data = conn->data;
2158 ssize_t nread;
2159 int what;
2160 int rc;
2161 char buf[120];
2162
2163 if(!connssl->ssl_ctx)
2164 return 0;
2165
2166 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
2167 return 0;
2168
2169 Curl_darwinssl_close(conn, sockindex);
2170
2171 rc = 0;
2172
2173 what = Curl_socket_ready(conn->sock[sockindex],Curl_socket_check(conn->sock[sockindex], -1, -1, 10000)
2174 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT)Curl_socket_check(conn->sock[sockindex], -1, -1, 10000);
2175
2176 for(;;) {
2177 if(what < 0) {
2178 /* anything that gets here is fatally bad */
2179 failfCurl_failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO((*__error())));
2180 rc = -1;
2181 break;
2182 }
2183
2184 if(!what) { /* timeout */
2185 failfCurl_failf(data, "SSL shutdown timeout");
2186 break;
2187 }
2188
2189 /* Something to read, let's do it and hope that it is the close
2190 notify alert from the server. No way to SSL_Read now, so use read(). */
2191
2192 nread = read(conn->sock[sockindex], buf, sizeof(buf));
2193
2194 if(nread < 0) {
2195 failfCurl_failf(data, "read: %s", strerror(errno(*__error())));
2196 rc = -1;
2197 }
2198
2199 if(nread <= 0)
2200 break;
2201
2202 what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0)Curl_socket_check(conn->sock[sockindex], -1, -1, 0);
2203 }
2204
2205 return rc;
2206}
2207
2208void Curl_darwinssl_session_free(void *ptr)
2209{
2210 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
2211 cached session ID inside the Security framework. There is a private
2212 function that does this, but I don't want to have to explain to you why I
2213 got your application rejected from the App Store due to the use of a
2214 private API, so the best we can do is free up our own char array that we
2215 created way back in darwinssl_connect_step1... */
2216 Curl_safefree(ptr)do {if((ptr)) {Curl_cfree((ptr)); (ptr) = ((void*)0);}} while
(0)
;
2217}
2218
2219size_t Curl_darwinssl_version(char *buffer, size_t size)
2220{
2221 return snprintfcurl_msnprintf(buffer, size, "SecureTransport");
2222}
2223
2224/*
2225 * This function uses SSLGetSessionState to determine connection status.
2226 *
2227 * Return codes:
2228 * 1 means the connection is still in place
2229 * 0 means the connection has been closed
2230 * -1 means the connection status is unknown
2231 */
2232int Curl_darwinssl_check_cxn(struct connectdata *conn)
2233{
2234 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET0];
2235 OSStatus err;
2236 SSLSessionState state;
2237
2238 if(connssl->ssl_ctx) {
2239 err = SSLGetSessionState(connssl->ssl_ctx, &state);
2240 if(err == noErr)
2241 return state == kSSLConnected || state == kSSLHandshake;
2242 return -1;
2243 }
2244 return 0;
2245}
2246
2247bool_Bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2248 int connindex)
2249{
2250 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2251 OSStatus err;
2252 size_t buffer;
2253
2254 if(connssl->ssl_ctx) { /* SSL is in use */
2255 err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
2256 if(err == noErr)
2257 return buffer > 0UL;
2258 return false0;
2259 }
2260 else
2261 return false0;
2262}
2263
2264void Curl_darwinssl_random(struct SessionHandle *data,
2265 unsigned char *entropy,
2266 size_t length)
2267{
2268 /* arc4random_buf() isn't available on cats older than Lion, so let's
2269 do this manually for the benefit of the older cats. */
2270 size_t i;
2271 u_int32_t random_number = 0;
2272
2273 for(i = 0 ; i < length ; i++) {
2274 if(i % sizeof(u_int32_t) == 0)
2275 random_number = arc4random();
2276 entropy[i] = random_number & 0xFF;
2277 random_number >>= 8;
2278 }
2279 i = random_number = 0;
Value stored to 'i' is never read
2280 (void)data;
2281}
2282
2283void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2284 size_t tmplen,
2285 unsigned char *md5sum, /* output */
2286 size_t md5len)
2287{
2288 (void)md5len;
2289 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2290}
2291
2292static ssize_t darwinssl_send(struct connectdata *conn,
2293 int sockindex,
2294 const void *mem,
2295 size_t len,
2296 CURLcode *curlcode)
2297{
2298 /*struct SessionHandle *data = conn->data;*/
2299 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2300 size_t processed = 0UL;
2301 OSStatus err;
2302
2303 /* The SSLWrite() function works a little differently than expected. The
2304 fourth argument (processed) is currently documented in Apple's
2305 documentation as: "On return, the length, in bytes, of the data actually
2306 written."
2307
2308 Now, one could interpret that as "written to the socket," but actually,
2309 it returns the amount of data that was written to a buffer internal to
2310 the SSLContextRef instead. So it's possible for SSLWrite() to return
2311 errSSLWouldBlock and a number of bytes "written" because those bytes were
2312 encrypted and written to a buffer, not to the socket.
2313
2314 So if this happens, then we need to keep calling SSLWrite() over and
2315 over again with no new data until it quits returning errSSLWouldBlock. */
2316
2317 /* Do we have buffered data to write from the last time we were called? */
2318 if(connssl->ssl_write_buffered_length) {
2319 /* Write the buffered data: */
2320 err = SSLWrite(connssl->ssl_ctx, NULL((void*)0), 0UL, &processed);
2321 switch (err) {
2322 case noErr:
2323 /* processed is always going to be 0 because we didn't write to
2324 the buffer, so return how much was written to the socket */
2325 processed = connssl->ssl_write_buffered_length;
2326 connssl->ssl_write_buffered_length = 0UL;
2327 break;
2328 case errSSLWouldBlock: /* argh, try again */
2329 *curlcode = CURLE_AGAIN;
2330 return -1L;
2331 default:
2332 failfCurl_failf(conn->data, "SSLWrite() returned error %d", err);
2333 *curlcode = CURLE_SEND_ERROR;
2334 return -1L;
2335 }
2336 }
2337 else {
2338 /* We've got new data to write: */
2339 err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
2340 if(err != noErr) {
2341 switch (err) {
2342 case errSSLWouldBlock:
2343 /* Data was buffered but not sent, we have to tell the caller
2344 to try sending again, and remember how much was buffered */
2345 connssl->ssl_write_buffered_length = len;
2346 *curlcode = CURLE_AGAIN;
2347 return -1L;
2348 default:
2349 failfCurl_failf(conn->data, "SSLWrite() returned error %d", err);
2350 *curlcode = CURLE_SEND_ERROR;
2351 return -1L;
2352 }
2353 }
2354 }
2355 return (ssize_t)processed;
2356}
2357
2358static ssize_t darwinssl_recv(struct connectdata *conn,
2359 int num,
2360 char *buf,
2361 size_t buffersize,
2362 CURLcode *curlcode)
2363{
2364 /*struct SessionHandle *data = conn->data;*/
2365 struct ssl_connect_data *connssl = &conn->ssl[num];
2366 size_t processed = 0UL;
2367 OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
2368
2369 if(err != noErr) {
2370 switch (err) {
2371 case errSSLWouldBlock: /* return how much we read (if anything) */
2372 if(processed)
2373 return (ssize_t)processed;
2374 *curlcode = CURLE_AGAIN;
2375 return -1L;
2376 break;
2377
2378 /* errSSLClosedGraceful - server gracefully shut down the SSL session
2379 errSSLClosedNoNotify - server hung up on us instead of sending a
2380 closure alert notice, read() is returning 0
2381 Either way, inform the caller that the server disconnected. */
2382 case errSSLClosedGraceful:
2383 case errSSLClosedNoNotify:
2384 *curlcode = CURLE_OK;
2385 return -1L;
2386 break;
2387
2388 default:
2389 failfCurl_failf(conn->data, "SSLRead() return error %d", err);
2390 *curlcode = CURLE_RECV_ERROR;
2391 return -1L;
2392 break;
2393 }
2394 }
2395 return (ssize_t)processed;
2396}
2397
2398#endif /* USE_DARWINSSL */