source: asp3_tinet_ecnl_arm/trunk/curl-7.57.0/lib/vtls/darwinssl.c@ 352

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

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 99.9 KB
Line 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012 - 2017, 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 macOS SecureTransport-specific code for the
26 * TLS/SSL layer. No code but vtls.c should ever call or use these functions.
27 */
28
29#include "curl_setup.h"
30
31#include "urldata.h" /* for the Curl_easy definition */
32#include "curl_base64.h"
33#include "strtok.h"
34
35#ifdef USE_DARWINSSL
36
37#ifdef __clang__
38#pragma clang diagnostic push
39#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
40#endif /* __clang__ */
41
42#ifdef HAVE_LIMITS_H
43#include <limits.h>
44#endif
45
46#include <Security/Security.h>
47/* For some reason, when building for iOS, the omnibus header above does
48 * not include SecureTransport.h as of iOS SDK 5.1. */
49#include <Security/SecureTransport.h>
50#include <CoreFoundation/CoreFoundation.h>
51#include <CommonCrypto/CommonDigest.h>
52
53/* The Security framework has changed greatly between iOS and different macOS
54 versions, and we will try to support as many of them as we can (back to
55 Leopard and iOS 5) by using macros and weak-linking.
56
57 In general, you want to build this using the most recent OS SDK, since some
58 features require curl to be built against the latest SDK. TLS 1.1 and 1.2
59 support, for instance, require the macOS 10.8 SDK or later. TLS 1.3
60 requires the macOS 10.13 or iOS 11 SDK or later. */
61#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
62
63#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
64#error "The darwinssl back-end requires Leopard or later."
65#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
66
67#define CURL_BUILD_IOS 0
68#define CURL_BUILD_IOS_7 0
69#define CURL_BUILD_IOS_11 0
70#define CURL_BUILD_MAC 1
71/* This is the maximum API level we are allowed to use when building: */
72#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
73#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
74#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
75#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
76#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
77#define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
78/* These macros mean "the following code is present to allow runtime backward
79 compatibility with at least this cat or earlier":
80 (You set this at build-time using the compiler command line option
81 "-mmacos-version-min.") */
82#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
83#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
84#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
85#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
86#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
87
88#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
89#define CURL_BUILD_IOS 1
90#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
91#define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
92#define CURL_BUILD_MAC 0
93#define CURL_BUILD_MAC_10_5 0
94#define CURL_BUILD_MAC_10_6 0
95#define CURL_BUILD_MAC_10_7 0
96#define CURL_BUILD_MAC_10_8 0
97#define CURL_BUILD_MAC_10_9 0
98#define CURL_BUILD_MAC_10_13 0
99#define CURL_SUPPORT_MAC_10_5 0
100#define CURL_SUPPORT_MAC_10_6 0
101#define CURL_SUPPORT_MAC_10_7 0
102#define CURL_SUPPORT_MAC_10_8 0
103#define CURL_SUPPORT_MAC_10_9 0
104
105#else
106#error "The darwinssl back-end requires iOS or OS X."
107#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
108
109#if CURL_BUILD_MAC
110#include <sys/sysctl.h>
111#endif /* CURL_BUILD_MAC */
112
113#include "urldata.h"
114#include "sendf.h"
115#include "inet_pton.h"
116#include "connect.h"
117#include "select.h"
118#include "vtls.h"
119#include "darwinssl.h"
120#include "curl_printf.h"
121
122#include "curl_memory.h"
123/* The last #include file should be: */
124#include "memdebug.h"
125
126/* From MacTypes.h (which we can't include because it isn't present in iOS: */
127#define ioErr -36
128#define paramErr -50
129
130struct ssl_backend_data {
131 SSLContextRef ssl_ctx;
132 curl_socket_t ssl_sockfd;
133 bool ssl_direction; /* true if writing, false if reading */
134 size_t ssl_write_buffered_length;
135};
136
137#define BACKEND connssl->backend
138
139/* pinned public key support tests */
140
141/* version 1 supports macOS 10.12+ and iOS 10+ */
142#if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \
143 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200))
144#define DARWIN_SSL_PINNEDPUBKEY_V1 1
145#endif
146
147/* version 2 supports MacOSX 10.7+ */
148#if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
149#define DARWIN_SSL_PINNEDPUBKEY_V2 1
150#endif
151
152#if defined(DARWIN_SSL_PINNEDPUBKEY_V1) || defined(DARWIN_SSL_PINNEDPUBKEY_V2)
153/* this backend supports CURLOPT_PINNEDPUBLICKEY */
154#define DARWIN_SSL_PINNEDPUBKEY 1
155#endif /* DARWIN_SSL_PINNEDPUBKEY */
156
157#ifdef DARWIN_SSL_PINNEDPUBKEY
158/* both new and old APIs return rsa keys missing the spki header (not DER) */
159static const unsigned char rsa4096SpkiHeader[] = {
160 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d,
161 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
162 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
163 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00};
164
165static const unsigned char rsa2048SpkiHeader[] = {
166 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
167 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
168 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
169 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00};
170#ifdef DARWIN_SSL_PINNEDPUBKEY_V1
171/* the *new* version doesn't return DER encoded ecdsa certs like the old... */
172static const unsigned char ecDsaSecp256r1SpkiHeader[] = {
173 0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
174 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
175 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48,
176 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
177 0x42, 0x00};
178
179static const unsigned char ecDsaSecp384r1SpkiHeader[] = {
180 0x30, 0x76, 0x30, 0x10, 0x06, 0x07,
181 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
182 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04,
183 0x00, 0x22, 0x03, 0x62, 0x00};
184#endif /* DARWIN_SSL_PINNEDPUBKEY_V1 */
185#endif /* DARWIN_SSL_PINNEDPUBKEY */
186
187/* The following two functions were ripped from Apple sample code,
188 * with some modifications: */
189static OSStatus SocketRead(SSLConnectionRef connection,
190 void *data, /* owned by
191 * caller, data
192 * RETURNED */
193 size_t *dataLength) /* IN/OUT */
194{
195 size_t bytesToGo = *dataLength;
196 size_t initLen = bytesToGo;
197 UInt8 *currData = (UInt8 *)data;
198 /*int sock = *(int *)connection;*/
199 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
200 int sock = BACKEND->ssl_sockfd;
201 OSStatus rtn = noErr;
202 size_t bytesRead;
203 ssize_t rrtn;
204 int theErr;
205
206 *dataLength = 0;
207
208 for(;;) {
209 bytesRead = 0;
210 rrtn = read(sock, currData, bytesToGo);
211 if(rrtn <= 0) {
212 /* this is guesswork... */
213 theErr = errno;
214 if(rrtn == 0) { /* EOF = server hung up */
215 /* the framework will turn this into errSSLClosedNoNotify */
216 rtn = errSSLClosedGraceful;
217 }
218 else /* do the switch */
219 switch(theErr) {
220 case ENOENT:
221 /* connection closed */
222 rtn = errSSLClosedGraceful;
223 break;
224 case ECONNRESET:
225 rtn = errSSLClosedAbort;
226 break;
227 case EAGAIN:
228 rtn = errSSLWouldBlock;
229 BACKEND->ssl_direction = false;
230 break;
231 default:
232 rtn = ioErr;
233 break;
234 }
235 break;
236 }
237 else {
238 bytesRead = rrtn;
239 }
240 bytesToGo -= bytesRead;
241 currData += bytesRead;
242
243 if(bytesToGo == 0) {
244 /* filled buffer with incoming data, done */
245 break;
246 }
247 }
248 *dataLength = initLen - bytesToGo;
249
250 return rtn;
251}
252
253static OSStatus SocketWrite(SSLConnectionRef connection,
254 const void *data,
255 size_t *dataLength) /* IN/OUT */
256{
257 size_t bytesSent = 0;
258 /*int sock = *(int *)connection;*/
259 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
260 int sock = BACKEND->ssl_sockfd;
261 ssize_t length;
262 size_t dataLen = *dataLength;
263 const UInt8 *dataPtr = (UInt8 *)data;
264 OSStatus ortn;
265 int theErr;
266
267 *dataLength = 0;
268
269 do {
270 length = write(sock,
271 (char *)dataPtr + bytesSent,
272 dataLen - bytesSent);
273 } while((length > 0) &&
274 ( (bytesSent += length) < dataLen) );
275
276 if(length <= 0) {
277 theErr = errno;
278 if(theErr == EAGAIN) {
279 ortn = errSSLWouldBlock;
280 BACKEND->ssl_direction = true;
281 }
282 else {
283 ortn = ioErr;
284 }
285 }
286 else {
287 ortn = noErr;
288 }
289 *dataLength = bytesSent;
290 return ortn;
291}
292
293#ifndef CURL_DISABLE_VERBOSE_STRINGS
294CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher)
295{
296 switch(cipher) {
297 /* SSL version 3.0 */
298 case SSL_RSA_WITH_NULL_MD5:
299 return "SSL_RSA_WITH_NULL_MD5";
300 break;
301 case SSL_RSA_WITH_NULL_SHA:
302 return "SSL_RSA_WITH_NULL_SHA";
303 break;
304 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
305 return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
306 break;
307 case SSL_RSA_WITH_RC4_128_MD5:
308 return "SSL_RSA_WITH_RC4_128_MD5";
309 break;
310 case SSL_RSA_WITH_RC4_128_SHA:
311 return "SSL_RSA_WITH_RC4_128_SHA";
312 break;
313 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
314 return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
315 break;
316 case SSL_RSA_WITH_IDEA_CBC_SHA:
317 return "SSL_RSA_WITH_IDEA_CBC_SHA";
318 break;
319 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
320 return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
321 break;
322 case SSL_RSA_WITH_DES_CBC_SHA:
323 return "SSL_RSA_WITH_DES_CBC_SHA";
324 break;
325 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
326 return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
327 break;
328 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
329 return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
330 break;
331 case SSL_DH_DSS_WITH_DES_CBC_SHA:
332 return "SSL_DH_DSS_WITH_DES_CBC_SHA";
333 break;
334 case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
335 return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
336 break;
337 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
338 return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
339 break;
340 case SSL_DH_RSA_WITH_DES_CBC_SHA:
341 return "SSL_DH_RSA_WITH_DES_CBC_SHA";
342 break;
343 case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
344 return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
345 break;
346 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
347 return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
348 break;
349 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
350 return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
351 break;
352 case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
353 return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
354 break;
355 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
356 return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
357 break;
358 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
359 return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
360 break;
361 case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
362 return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
363 break;
364 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
365 return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
366 break;
367 case SSL_DH_anon_WITH_RC4_128_MD5:
368 return "SSL_DH_anon_WITH_RC4_128_MD5";
369 break;
370 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
371 return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
372 break;
373 case SSL_DH_anon_WITH_DES_CBC_SHA:
374 return "SSL_DH_anon_WITH_DES_CBC_SHA";
375 break;
376 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
377 return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
378 break;
379 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
380 return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
381 break;
382 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
383 return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
384 break;
385 /* TLS 1.0 with AES (RFC 3268)
386 (Apparently these are used in SSLv3 implementations as well.) */
387 case TLS_RSA_WITH_AES_128_CBC_SHA:
388 return "TLS_RSA_WITH_AES_128_CBC_SHA";
389 break;
390 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
391 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
392 break;
393 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
394 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
395 break;
396 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
397 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
398 break;
399 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
400 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
401 break;
402 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
403 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
404 break;
405 case TLS_RSA_WITH_AES_256_CBC_SHA:
406 return "TLS_RSA_WITH_AES_256_CBC_SHA";
407 break;
408 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
409 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
410 break;
411 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
412 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
413 break;
414 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
415 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
416 break;
417 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
418 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
419 break;
420 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
421 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
422 break;
423 /* SSL version 2.0 */
424 case SSL_RSA_WITH_RC2_CBC_MD5:
425 return "SSL_RSA_WITH_RC2_CBC_MD5";
426 break;
427 case SSL_RSA_WITH_IDEA_CBC_MD5:
428 return "SSL_RSA_WITH_IDEA_CBC_MD5";
429 break;
430 case SSL_RSA_WITH_DES_CBC_MD5:
431 return "SSL_RSA_WITH_DES_CBC_MD5";
432 break;
433 case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
434 return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
435 break;
436 }
437 return "SSL_NULL_WITH_NULL_NULL";
438}
439
440CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
441{
442 switch(cipher) {
443 /* TLS 1.0 with AES (RFC 3268) */
444 case TLS_RSA_WITH_AES_128_CBC_SHA:
445 return "TLS_RSA_WITH_AES_128_CBC_SHA";
446 break;
447 case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
448 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
449 break;
450 case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
451 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
452 break;
453 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
454 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
455 break;
456 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
457 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
458 break;
459 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
460 return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
461 break;
462 case TLS_RSA_WITH_AES_256_CBC_SHA:
463 return "TLS_RSA_WITH_AES_256_CBC_SHA";
464 break;
465 case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
466 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
467 break;
468 case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
469 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
470 break;
471 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
472 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
473 break;
474 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
475 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
476 break;
477 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
478 return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
479 break;
480#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
481 /* TLS 1.0 with ECDSA (RFC 4492) */
482 case TLS_ECDH_ECDSA_WITH_NULL_SHA:
483 return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
484 break;
485 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
486 return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
487 break;
488 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
489 return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
490 break;
491 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
492 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
493 break;
494 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
495 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
496 break;
497 case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
498 return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
499 break;
500 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
501 return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
502 break;
503 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
504 return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
505 break;
506 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
507 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
508 break;
509 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
510 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
511 break;
512 case TLS_ECDH_RSA_WITH_NULL_SHA:
513 return "TLS_ECDH_RSA_WITH_NULL_SHA";
514 break;
515 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
516 return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
517 break;
518 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
519 return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
520 break;
521 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
522 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
523 break;
524 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
525 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
526 break;
527 case TLS_ECDHE_RSA_WITH_NULL_SHA:
528 return "TLS_ECDHE_RSA_WITH_NULL_SHA";
529 break;
530 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
531 return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
532 break;
533 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
534 return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
535 break;
536 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
537 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
538 break;
539 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
540 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
541 break;
542 case TLS_ECDH_anon_WITH_NULL_SHA:
543 return "TLS_ECDH_anon_WITH_NULL_SHA";
544 break;
545 case TLS_ECDH_anon_WITH_RC4_128_SHA:
546 return "TLS_ECDH_anon_WITH_RC4_128_SHA";
547 break;
548 case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
549 return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
550 break;
551 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
552 return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
553 break;
554 case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
555 return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
556 break;
557#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
558#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
559 /* TLS 1.2 (RFC 5246) */
560 case TLS_RSA_WITH_NULL_MD5:
561 return "TLS_RSA_WITH_NULL_MD5";
562 break;
563 case TLS_RSA_WITH_NULL_SHA:
564 return "TLS_RSA_WITH_NULL_SHA";
565 break;
566 case TLS_RSA_WITH_RC4_128_MD5:
567 return "TLS_RSA_WITH_RC4_128_MD5";
568 break;
569 case TLS_RSA_WITH_RC4_128_SHA:
570 return "TLS_RSA_WITH_RC4_128_SHA";
571 break;
572 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
573 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
574 break;
575 case TLS_RSA_WITH_NULL_SHA256:
576 return "TLS_RSA_WITH_NULL_SHA256";
577 break;
578 case TLS_RSA_WITH_AES_128_CBC_SHA256:
579 return "TLS_RSA_WITH_AES_128_CBC_SHA256";
580 break;
581 case TLS_RSA_WITH_AES_256_CBC_SHA256:
582 return "TLS_RSA_WITH_AES_256_CBC_SHA256";
583 break;
584 case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
585 return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
586 break;
587 case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
588 return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
589 break;
590 case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
591 return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
592 break;
593 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
594 return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
595 break;
596 case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
597 return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
598 break;
599 case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
600 return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
601 break;
602 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
603 return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
604 break;
605 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
606 return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
607 break;
608 case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
609 return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
610 break;
611 case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
612 return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
613 break;
614 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
615 return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
616 break;
617 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
618 return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
619 break;
620 case TLS_DH_anon_WITH_RC4_128_MD5:
621 return "TLS_DH_anon_WITH_RC4_128_MD5";
622 break;
623 case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
624 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
625 break;
626 case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
627 return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
628 break;
629 case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
630 return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
631 break;
632 /* TLS 1.2 with AES GCM (RFC 5288) */
633 case TLS_RSA_WITH_AES_128_GCM_SHA256:
634 return "TLS_RSA_WITH_AES_128_GCM_SHA256";
635 break;
636 case TLS_RSA_WITH_AES_256_GCM_SHA384:
637 return "TLS_RSA_WITH_AES_256_GCM_SHA384";
638 break;
639 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
640 return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
641 break;
642 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
643 return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
644 break;
645 case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
646 return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
647 break;
648 case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
649 return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
650 break;
651 case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
652 return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
653 break;
654 case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
655 return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
656 break;
657 case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
658 return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
659 break;
660 case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
661 return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
662 break;
663 case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
664 return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
665 break;
666 case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
667 return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
668 break;
669 /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
670 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
671 return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
672 break;
673 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
674 return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
675 break;
676 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
677 return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
678 break;
679 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
680 return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
681 break;
682 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
683 return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
684 break;
685 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
686 return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
687 break;
688 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
689 return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
690 break;
691 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
692 return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
693 break;
694 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
695 return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
696 break;
697 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
698 return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
699 break;
700 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
701 return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
702 break;
703 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
704 return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
705 break;
706 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
707 return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
708 break;
709 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
710 return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
711 break;
712 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
713 return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
714 break;
715 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
716 return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
717 break;
718 case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
719 return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
720 break;
721#else
722 case SSL_RSA_WITH_NULL_MD5:
723 return "TLS_RSA_WITH_NULL_MD5";
724 break;
725 case SSL_RSA_WITH_NULL_SHA:
726 return "TLS_RSA_WITH_NULL_SHA";
727 break;
728 case SSL_RSA_WITH_RC4_128_MD5:
729 return "TLS_RSA_WITH_RC4_128_MD5";
730 break;
731 case SSL_RSA_WITH_RC4_128_SHA:
732 return "TLS_RSA_WITH_RC4_128_SHA";
733 break;
734 case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
735 return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
736 break;
737 case SSL_DH_anon_WITH_RC4_128_MD5:
738 return "TLS_DH_anon_WITH_RC4_128_MD5";
739 break;
740 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
741 return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
742 break;
743#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
744#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
745 /* TLS PSK (RFC 4279): */
746 case TLS_PSK_WITH_RC4_128_SHA:
747 return "TLS_PSK_WITH_RC4_128_SHA";
748 break;
749 case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
750 return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
751 break;
752 case TLS_PSK_WITH_AES_128_CBC_SHA:
753 return "TLS_PSK_WITH_AES_128_CBC_SHA";
754 break;
755 case TLS_PSK_WITH_AES_256_CBC_SHA:
756 return "TLS_PSK_WITH_AES_256_CBC_SHA";
757 break;
758 case TLS_DHE_PSK_WITH_RC4_128_SHA:
759 return "TLS_DHE_PSK_WITH_RC4_128_SHA";
760 break;
761 case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
762 return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
763 break;
764 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
765 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
766 break;
767 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
768 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
769 break;
770 case TLS_RSA_PSK_WITH_RC4_128_SHA:
771 return "TLS_RSA_PSK_WITH_RC4_128_SHA";
772 break;
773 case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
774 return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
775 break;
776 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
777 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
778 break;
779 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
780 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
781 break;
782 /* More TLS PSK (RFC 4785): */
783 case TLS_PSK_WITH_NULL_SHA:
784 return "TLS_PSK_WITH_NULL_SHA";
785 break;
786 case TLS_DHE_PSK_WITH_NULL_SHA:
787 return "TLS_DHE_PSK_WITH_NULL_SHA";
788 break;
789 case TLS_RSA_PSK_WITH_NULL_SHA:
790 return "TLS_RSA_PSK_WITH_NULL_SHA";
791 break;
792 /* Even more TLS PSK (RFC 5487): */
793 case TLS_PSK_WITH_AES_128_GCM_SHA256:
794 return "TLS_PSK_WITH_AES_128_GCM_SHA256";
795 break;
796 case TLS_PSK_WITH_AES_256_GCM_SHA384:
797 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
798 break;
799 case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
800 return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
801 break;
802 case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
803 return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
804 break;
805 case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
806 return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
807 break;
808 case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
809 return "TLS_PSK_WITH_AES_256_GCM_SHA384";
810 break;
811 case TLS_PSK_WITH_AES_128_CBC_SHA256:
812 return "TLS_PSK_WITH_AES_128_CBC_SHA256";
813 break;
814 case TLS_PSK_WITH_AES_256_CBC_SHA384:
815 return "TLS_PSK_WITH_AES_256_CBC_SHA384";
816 break;
817 case TLS_PSK_WITH_NULL_SHA256:
818 return "TLS_PSK_WITH_NULL_SHA256";
819 break;
820 case TLS_PSK_WITH_NULL_SHA384:
821 return "TLS_PSK_WITH_NULL_SHA384";
822 break;
823 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
824 return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
825 break;
826 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
827 return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
828 break;
829 case TLS_DHE_PSK_WITH_NULL_SHA256:
830 return "TLS_DHE_PSK_WITH_NULL_SHA256";
831 break;
832 case TLS_DHE_PSK_WITH_NULL_SHA384:
833 return "TLS_RSA_PSK_WITH_NULL_SHA384";
834 break;
835 case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
836 return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
837 break;
838 case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
839 return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
840 break;
841 case TLS_RSA_PSK_WITH_NULL_SHA256:
842 return "TLS_RSA_PSK_WITH_NULL_SHA256";
843 break;
844 case TLS_RSA_PSK_WITH_NULL_SHA384:
845 return "TLS_RSA_PSK_WITH_NULL_SHA384";
846 break;
847#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
848#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
849 /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */
850 case TLS_AES_128_GCM_SHA256:
851 return "TLS_AES_128_GCM_SHA256";
852 break;
853 case TLS_AES_256_GCM_SHA384:
854 return "TLS_AES_256_GCM_SHA384";
855 break;
856 case TLS_CHACHA20_POLY1305_SHA256:
857 return "TLS_CHACHA20_POLY1305_SHA256";
858 break;
859 case TLS_AES_128_CCM_SHA256:
860 return "TLS_AES_128_CCM_SHA256";
861 break;
862 case TLS_AES_128_CCM_8_SHA256:
863 return "TLS_AES_128_CCM_8_SHA256";
864 break;
865 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
866 return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
867 break;
868 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
869 return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
870 break;
871#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
872 }
873 return "TLS_NULL_WITH_NULL_NULL";
874}
875#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
876
877#if CURL_BUILD_MAC
878CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
879{
880 int mib[2];
881 char *os_version;
882 size_t os_version_len;
883 char *os_version_major, *os_version_minor;
884 char *tok_buf;
885
886 /* Get the Darwin kernel version from the kernel using sysctl(): */
887 mib[0] = CTL_KERN;
888 mib[1] = KERN_OSRELEASE;
889 if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
890 return;
891 os_version = malloc(os_version_len*sizeof(char));
892 if(!os_version)
893 return;
894 if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
895 free(os_version);
896 return;
897 }
898
899 /* Parse the version: */
900 os_version_major = strtok_r(os_version, ".", &tok_buf);
901 os_version_minor = strtok_r(NULL, ".", &tok_buf);
902 *major = atoi(os_version_major);
903 *minor = atoi(os_version_minor);
904 free(os_version);
905}
906#endif /* CURL_BUILD_MAC */
907
908/* Apple provides a myriad of ways of getting information about a certificate
909 into a string. Some aren't available under iOS or newer cats. So here's
910 a unified function for getting a string describing the certificate that
911 ought to work in all cats starting with Leopard. */
912CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
913{
914 CFStringRef server_cert_summary = CFSTR("(null)");
915
916#if CURL_BUILD_IOS
917 /* iOS: There's only one way to do this. */
918 server_cert_summary = SecCertificateCopySubjectSummary(cert);
919#else
920#if CURL_BUILD_MAC_10_7
921 /* Lion & later: Get the long description if we can. */
922 if(SecCertificateCopyLongDescription != NULL)
923 server_cert_summary =
924 SecCertificateCopyLongDescription(NULL, cert, NULL);
925 else
926#endif /* CURL_BUILD_MAC_10_7 */
927#if CURL_BUILD_MAC_10_6
928 /* Snow Leopard: Get the certificate summary. */
929 if(SecCertificateCopySubjectSummary != NULL)
930 server_cert_summary = SecCertificateCopySubjectSummary(cert);
931 else
932#endif /* CURL_BUILD_MAC_10_6 */
933 /* Leopard is as far back as we go... */
934 (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
935#endif /* CURL_BUILD_IOS */
936 return server_cert_summary;
937}
938
939static CURLcode CopyCertSubject(struct Curl_easy *data,
940 SecCertificateRef cert, char **certp)
941{
942 CFStringRef c = getsubject(cert);
943 CURLcode result = CURLE_OK;
944 const char *direct;
945 char *cbuf = NULL;
946 *certp = NULL;
947
948 if(!c) {
949 failf(data, "SSL: invalid CA certificate subject");
950 return CURLE_OUT_OF_MEMORY;
951 }
952
953 /* If the subject is already available as UTF-8 encoded (ie 'direct') then
954 use that, else convert it. */
955 direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8);
956 if(direct) {
957 *certp = strdup(direct);
958 if(!*certp) {
959 failf(data, "SSL: out of memory");
960 result = CURLE_OUT_OF_MEMORY;
961 }
962 }
963 else {
964 size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1;
965 cbuf = calloc(cbuf_size, 1);
966 if(cbuf) {
967 if(!CFStringGetCString(c, cbuf, cbuf_size,
968 kCFStringEncodingUTF8)) {
969 failf(data, "SSL: invalid CA certificate subject");
970 result = CURLE_SSL_CACERT;
971 }
972 else
973 /* pass back the buffer */
974 *certp = cbuf;
975 }
976 else {
977 failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size);
978 result = CURLE_OUT_OF_MEMORY;
979 }
980 }
981 if(result)
982 free(cbuf);
983 CFRelease(c);
984 return result;
985}
986
987#if CURL_SUPPORT_MAC_10_6
988/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
989 deprecation warnings, so let's not compile this unless it's necessary: */
990static OSStatus CopyIdentityWithLabelOldSchool(char *label,
991 SecIdentityRef *out_c_a_k)
992{
993 OSStatus status = errSecItemNotFound;
994 SecKeychainAttributeList attr_list;
995 SecKeychainAttribute attr;
996 SecKeychainSearchRef search = NULL;
997 SecCertificateRef cert = NULL;
998
999 /* Set up the attribute list: */
1000 attr_list.count = 1L;
1001 attr_list.attr = &attr;
1002
1003 /* Set up our lone search criterion: */
1004 attr.tag = kSecLabelItemAttr;
1005 attr.data = label;
1006 attr.length = (UInt32)strlen(label);
1007
1008 /* Start searching: */
1009 status = SecKeychainSearchCreateFromAttributes(NULL,
1010 kSecCertificateItemClass,
1011 &attr_list,
1012 &search);
1013 if(status == noErr) {
1014 status = SecKeychainSearchCopyNext(search,
1015 (SecKeychainItemRef *)&cert);
1016 if(status == noErr && cert) {
1017 /* If we found a certificate, does it have a private key? */
1018 status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
1019 CFRelease(cert);
1020 }
1021 }
1022
1023 if(search)
1024 CFRelease(search);
1025 return status;
1026}
1027#endif /* CURL_SUPPORT_MAC_10_6 */
1028
1029static OSStatus CopyIdentityWithLabel(char *label,
1030 SecIdentityRef *out_cert_and_key)
1031{
1032 OSStatus status = errSecItemNotFound;
1033
1034#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1035 CFArrayRef keys_list;
1036 CFIndex keys_list_count;
1037 CFIndex i;
1038 CFStringRef common_name;
1039
1040 /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
1041 kSecClassIdentity was introduced in Lion. If both exist, let's use them
1042 to find the certificate. */
1043 if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
1044 CFTypeRef keys[5];
1045 CFTypeRef values[5];
1046 CFDictionaryRef query_dict;
1047 CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
1048 kCFStringEncodingUTF8);
1049
1050 /* Set up our search criteria and expected results: */
1051 values[0] = kSecClassIdentity; /* we want a certificate and a key */
1052 keys[0] = kSecClass;
1053 values[1] = kCFBooleanTrue; /* we want a reference */
1054 keys[1] = kSecReturnRef;
1055 values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the
1056 * label matching below worked correctly */
1057 keys[2] = kSecMatchLimit;
1058 /* identity searches need a SecPolicyRef in order to work */
1059 values[3] = SecPolicyCreateSSL(false, NULL);
1060 keys[3] = kSecMatchPolicy;
1061 /* match the name of the certificate (doesn't work in macOS 10.12.1) */
1062 values[4] = label_cf;
1063 keys[4] = kSecAttrLabel;
1064 query_dict = CFDictionaryCreate(NULL, (const void **)keys,
1065 (const void **)values, 5L,
1066 &kCFCopyStringDictionaryKeyCallBacks,
1067 &kCFTypeDictionaryValueCallBacks);
1068 CFRelease(values[3]);
1069
1070 /* Do we have a match? */
1071 status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
1072
1073 /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity,
1074 * we need to find the correct identity ourselves */
1075 if(status == noErr) {
1076 keys_list_count = CFArrayGetCount(keys_list);
1077 *out_cert_and_key = NULL;
1078 status = 1;
1079 for(i = 0; i<keys_list_count; i++) {
1080 OSStatus err = noErr;
1081 SecCertificateRef cert = NULL;
1082 SecIdentityRef identity =
1083 (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
1084 err = SecIdentityCopyCertificate(identity, &cert);
1085 if(err == noErr) {
1086#if CURL_BUILD_IOS
1087 common_name = SecCertificateCopySubjectSummary(cert);
1088#elif CURL_BUILD_MAC_10_7
1089 SecCertificateCopyCommonName(cert, &common_name);
1090#endif
1091 if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
1092 CFRelease(cert);
1093 CFRelease(common_name);
1094 CFRetain(identity);
1095 *out_cert_and_key = identity;
1096 status = noErr;
1097 break;
1098 }
1099 CFRelease(common_name);
1100 }
1101 CFRelease(cert);
1102 }
1103 }
1104
1105 if(keys_list)
1106 CFRelease(keys_list);
1107 CFRelease(query_dict);
1108 CFRelease(label_cf);
1109 }
1110 else {
1111#if CURL_SUPPORT_MAC_10_6
1112 /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
1113 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1114#endif /* CURL_SUPPORT_MAC_10_6 */
1115 }
1116#elif CURL_SUPPORT_MAC_10_6
1117 /* For developers building on older cats, we have no choice but to fall back
1118 to SecKeychainSearch. */
1119 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1120#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1121 return status;
1122}
1123
1124static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
1125 const char *cPassword,
1126 SecIdentityRef *out_cert_and_key)
1127{
1128 OSStatus status = errSecItemNotFound;
1129 CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
1130 (const UInt8 *)cPath, strlen(cPath), false);
1131 CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
1132 cPassword, kCFStringEncodingUTF8) : NULL;
1133 CFDataRef pkcs_data = NULL;
1134
1135 /* We can import P12 files on iOS or OS X 10.7 or later: */
1136 /* These constants are documented as having first appeared in 10.6 but they
1137 raise linker errors when used on that cat for some reason. */
1138#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1139 if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
1140 NULL, NULL, &status)) {
1141 const void *cKeys[] = {kSecImportExportPassphrase};
1142 const void *cValues[] = {password};
1143 CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
1144 password ? 1L : 0L, NULL, NULL);
1145 CFArrayRef items = NULL;
1146
1147 /* Here we go: */
1148 status = SecPKCS12Import(pkcs_data, options, &items);
1149 if(status == errSecSuccess && items && CFArrayGetCount(items)) {
1150 CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
1151 const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
1152 kSecImportItemIdentity);
1153
1154 /* Retain the identity; we don't care about any other data... */
1155 CFRetain(temp_identity);
1156 *out_cert_and_key = (SecIdentityRef)temp_identity;
1157 }
1158
1159 if(items)
1160 CFRelease(items);
1161 CFRelease(options);
1162 CFRelease(pkcs_data);
1163 }
1164#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1165 if(password)
1166 CFRelease(password);
1167 CFRelease(pkcs_url);
1168 return status;
1169}
1170
1171/* This code was borrowed from nss.c, with some modifications:
1172 * Determine whether the nickname passed in is a filename that needs to
1173 * be loaded as a PEM or a regular NSS nickname.
1174 *
1175 * returns 1 for a file
1176 * returns 0 for not a file
1177 */
1178CF_INLINE bool is_file(const char *filename)
1179{
1180 struct_stat st;
1181
1182 if(filename == NULL)
1183 return false;
1184
1185 if(stat(filename, &st) == 0)
1186 return S_ISREG(st.st_mode);
1187 return false;
1188}
1189
1190#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1191static CURLcode darwinssl_version_from_curl(SSLProtocol *darwinver,
1192 long ssl_version)
1193{
1194 switch(ssl_version) {
1195 case CURL_SSLVERSION_TLSv1_0:
1196 *darwinver = kTLSProtocol1;
1197 return CURLE_OK;
1198 case CURL_SSLVERSION_TLSv1_1:
1199 *darwinver = kTLSProtocol11;
1200 return CURLE_OK;
1201 case CURL_SSLVERSION_TLSv1_2:
1202 *darwinver = kTLSProtocol12;
1203 return CURLE_OK;
1204 case CURL_SSLVERSION_TLSv1_3:
1205 /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */
1206#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
1207 /* We can assume __builtin_available() will always work in the
1208 10.13/11.0 SDK: */
1209 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1210 *darwinver = kTLSProtocol13;
1211 return CURLE_OK;
1212 }
1213#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
1214 break;
1215 }
1216 return CURLE_SSL_CONNECT_ERROR;
1217}
1218#endif
1219
1220static CURLcode
1221set_ssl_version_min_max(struct connectdata *conn, int sockindex)
1222{
1223 struct Curl_easy *data = conn->data;
1224 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1225 long ssl_version = SSL_CONN_CONFIG(version);
1226 long ssl_version_max = SSL_CONN_CONFIG(version_max);
1227 long max_supported_version_by_os;
1228
1229 /* macOS 10.5-10.7 supported TLS 1.0 only.
1230 macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
1231 macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
1232#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
1233 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1234 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3;
1235 }
1236 else {
1237 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1238 }
1239#else
1240 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1241#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
1242
1243 switch(ssl_version) {
1244 case CURL_SSLVERSION_DEFAULT:
1245 case CURL_SSLVERSION_TLSv1:
1246 ssl_version = CURL_SSLVERSION_TLSv1_0;
1247 ssl_version_max = max_supported_version_by_os;
1248 break;
1249 }
1250
1251 switch(ssl_version_max) {
1252 case CURL_SSLVERSION_MAX_NONE:
1253 ssl_version_max = ssl_version << 16;
1254 break;
1255 case CURL_SSLVERSION_MAX_DEFAULT:
1256 ssl_version_max = max_supported_version_by_os;
1257 break;
1258 }
1259
1260#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1261 if(SSLSetProtocolVersionMax != NULL) {
1262 SSLProtocol darwin_ver_min = kTLSProtocol1;
1263 SSLProtocol darwin_ver_max = kTLSProtocol1;
1264 CURLcode result = darwinssl_version_from_curl(&darwin_ver_min,
1265 ssl_version);
1266 if(result) {
1267 failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
1268 return result;
1269 }
1270 result = darwinssl_version_from_curl(&darwin_ver_max,
1271 ssl_version_max >> 16);
1272 if(result) {
1273 failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
1274 return result;
1275 }
1276
1277 (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, darwin_ver_min);
1278 (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, darwin_ver_max);
1279 return result;
1280 }
1281 else {
1282#if CURL_SUPPORT_MAC_10_8
1283 long i = ssl_version;
1284 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1285 kSSLProtocolAll,
1286 false);
1287 for(; i <= (ssl_version_max >> 16); i++) {
1288 switch(i) {
1289 case CURL_SSLVERSION_TLSv1_0:
1290 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1291 kTLSProtocol1,
1292 true);
1293 break;
1294 case CURL_SSLVERSION_TLSv1_1:
1295 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1296 kTLSProtocol11,
1297 true);
1298 break;
1299 case CURL_SSLVERSION_TLSv1_2:
1300 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1301 kTLSProtocol12,
1302 true);
1303 break;
1304 case CURL_SSLVERSION_TLSv1_3:
1305 failf(data, "Your version of the OS does not support TLSv1.3");
1306 return CURLE_SSL_CONNECT_ERROR;
1307 }
1308 }
1309 return CURLE_OK;
1310#endif /* CURL_SUPPORT_MAC_10_8 */
1311 }
1312#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1313 failf(data, "DarwinSSL: cannot set SSL protocol");
1314 return CURLE_SSL_CONNECT_ERROR;
1315}
1316
1317
1318static CURLcode darwinssl_connect_step1(struct connectdata *conn,
1319 int sockindex)
1320{
1321 struct Curl_easy *data = conn->data;
1322 curl_socket_t sockfd = conn->sock[sockindex];
1323 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1324 const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
1325 const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
1326 char * const ssl_cert = SSL_SET_OPTION(cert);
1327 const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
1328 conn->host.name;
1329 const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
1330#ifdef ENABLE_IPV6
1331 struct in6_addr addr;
1332#else
1333 struct in_addr addr;
1334#endif /* ENABLE_IPV6 */
1335 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1336 SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1337 OSStatus err = noErr;
1338#if CURL_BUILD_MAC
1339 int darwinver_maj = 0, darwinver_min = 0;
1340
1341 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1342#endif /* CURL_BUILD_MAC */
1343
1344#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1345 if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
1346 if(BACKEND->ssl_ctx)
1347 CFRelease(BACKEND->ssl_ctx);
1348 BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1349 if(!BACKEND->ssl_ctx) {
1350 failf(data, "SSL: couldn't create a context!");
1351 return CURLE_OUT_OF_MEMORY;
1352 }
1353 }
1354 else {
1355 /* The old ST API does not exist under iOS, so don't compile it: */
1356#if CURL_SUPPORT_MAC_10_8
1357 if(BACKEND->ssl_ctx)
1358 (void)SSLDisposeContext(BACKEND->ssl_ctx);
1359 err = SSLNewContext(false, &(BACKEND->ssl_ctx));
1360 if(err != noErr) {
1361 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1362 return CURLE_OUT_OF_MEMORY;
1363 }
1364#endif /* CURL_SUPPORT_MAC_10_8 */
1365 }
1366#else
1367 if(BACKEND->ssl_ctx)
1368 (void)SSLDisposeContext(BACKEND->ssl_ctx);
1369 err = SSLNewContext(false, &(BACKEND->ssl_ctx));
1370 if(err != noErr) {
1371 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1372 return CURLE_OUT_OF_MEMORY;
1373 }
1374#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1375 BACKEND->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1376
1377 /* check to see if we've been told to use an explicit SSL/TLS version */
1378#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1379 if(SSLSetProtocolVersionMax != NULL) {
1380 switch(conn->ssl_config.version) {
1381 case CURL_SSLVERSION_DEFAULT:
1382 case CURL_SSLVERSION_TLSv1:
1383 (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
1384#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
1385 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1386 (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol13);
1387 }
1388 else {
1389 (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
1390 }
1391#else
1392 (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
1393#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
1394 break;
1395 case CURL_SSLVERSION_TLSv1_0:
1396 case CURL_SSLVERSION_TLSv1_1:
1397 case CURL_SSLVERSION_TLSv1_2:
1398 case CURL_SSLVERSION_TLSv1_3:
1399 {
1400 CURLcode result = set_ssl_version_min_max(conn, sockindex);
1401 if(result != CURLE_OK)
1402 return result;
1403 break;
1404 }
1405 case CURL_SSLVERSION_SSLv3:
1406 err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol3);
1407 if(err != noErr) {
1408 failf(data, "Your version of the OS does not support SSLv3");
1409 return CURLE_SSL_CONNECT_ERROR;
1410 }
1411 (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol3);
1412 break;
1413 case CURL_SSLVERSION_SSLv2:
1414 err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol2);
1415 if(err != noErr) {
1416 failf(data, "Your version of the OS does not support SSLv2");
1417 return CURLE_SSL_CONNECT_ERROR;
1418 }
1419 (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol2);
1420 break;
1421 default:
1422 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1423 return CURLE_SSL_CONNECT_ERROR;
1424 }
1425 }
1426 else {
1427#if CURL_SUPPORT_MAC_10_8
1428 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1429 kSSLProtocolAll,
1430 false);
1431 switch(conn->ssl_config.version) {
1432 case CURL_SSLVERSION_DEFAULT:
1433 case CURL_SSLVERSION_TLSv1:
1434 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1435 kTLSProtocol1,
1436 true);
1437 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1438 kTLSProtocol11,
1439 true);
1440 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1441 kTLSProtocol12,
1442 true);
1443 break;
1444 case CURL_SSLVERSION_TLSv1_0:
1445 case CURL_SSLVERSION_TLSv1_1:
1446 case CURL_SSLVERSION_TLSv1_2:
1447 case CURL_SSLVERSION_TLSv1_3:
1448 {
1449 CURLcode result = set_ssl_version_min_max(conn, sockindex);
1450 if(result != CURLE_OK)
1451 return result;
1452 break;
1453 }
1454 case CURL_SSLVERSION_SSLv3:
1455 err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1456 kSSLProtocol3,
1457 true);
1458 if(err != noErr) {
1459 failf(data, "Your version of the OS does not support SSLv3");
1460 return CURLE_SSL_CONNECT_ERROR;
1461 }
1462 break;
1463 case CURL_SSLVERSION_SSLv2:
1464 err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1465 kSSLProtocol2,
1466 true);
1467 if(err != noErr) {
1468 failf(data, "Your version of the OS does not support SSLv2");
1469 return CURLE_SSL_CONNECT_ERROR;
1470 }
1471 break;
1472 default:
1473 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1474 return CURLE_SSL_CONNECT_ERROR;
1475 }
1476#endif /* CURL_SUPPORT_MAC_10_8 */
1477 }
1478#else
1479 if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
1480 failf(data, "Your version of the OS does not support to set maximum"
1481 " SSL/TLS version");
1482 return CURLE_SSL_CONNECT_ERROR;
1483 }
1484 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, kSSLProtocolAll, false);
1485 switch(conn->ssl_config.version) {
1486 case CURL_SSLVERSION_DEFAULT:
1487 case CURL_SSLVERSION_TLSv1:
1488 case CURL_SSLVERSION_TLSv1_0:
1489 (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1490 kTLSProtocol1,
1491 true);
1492 break;
1493 case CURL_SSLVERSION_TLSv1_1:
1494 failf(data, "Your version of the OS does not support TLSv1.1");
1495 return CURLE_SSL_CONNECT_ERROR;
1496 case CURL_SSLVERSION_TLSv1_2:
1497 failf(data, "Your version of the OS does not support TLSv1.2");
1498 return CURLE_SSL_CONNECT_ERROR;
1499 case CURL_SSLVERSION_TLSv1_3:
1500 failf(data, "Your version of the OS does not support TLSv1.3");
1501 return CURLE_SSL_CONNECT_ERROR;
1502 case CURL_SSLVERSION_SSLv2:
1503 err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1504 kSSLProtocol2,
1505 true);
1506 if(err != noErr) {
1507 failf(data, "Your version of the OS does not support SSLv2");
1508 return CURLE_SSL_CONNECT_ERROR;
1509 }
1510 break;
1511 case CURL_SSLVERSION_SSLv3:
1512 err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1513 kSSLProtocol3,
1514 true);
1515 if(err != noErr) {
1516 failf(data, "Your version of the OS does not support SSLv3");
1517 return CURLE_SSL_CONNECT_ERROR;
1518 }
1519 break;
1520 default:
1521 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1522 return CURLE_SSL_CONNECT_ERROR;
1523 }
1524#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1525
1526 if(SSL_SET_OPTION(key)) {
1527 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1528 "Transport. The private key must be in the Keychain.\n");
1529 }
1530
1531 if(ssl_cert) {
1532 SecIdentityRef cert_and_key = NULL;
1533 bool is_cert_file = is_file(ssl_cert);
1534
1535 /* User wants to authenticate with a client cert. Look for it:
1536 If we detect that this is a file on disk, then let's load it.
1537 Otherwise, assume that the user wants to use an identity loaded
1538 from the Keychain. */
1539 if(is_cert_file) {
1540 if(!SSL_SET_OPTION(cert_type))
1541 infof(data, "WARNING: SSL: Certificate type not set, assuming "
1542 "PKCS#12 format.\n");
1543 else if(strncmp(SSL_SET_OPTION(cert_type), "P12",
1544 strlen(SSL_SET_OPTION(cert_type))) != 0)
1545 infof(data, "WARNING: SSL: The Security framework only supports "
1546 "loading identities that are in PKCS#12 format.\n");
1547
1548 err = CopyIdentityFromPKCS12File(ssl_cert,
1549 SSL_SET_OPTION(key_passwd), &cert_and_key);
1550 }
1551 else
1552 err = CopyIdentityWithLabel(ssl_cert, &cert_and_key);
1553
1554 if(err == noErr && cert_and_key) {
1555 SecCertificateRef cert = NULL;
1556 CFTypeRef certs_c[1];
1557 CFArrayRef certs;
1558
1559 /* If we found one, print it out: */
1560 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1561 if(err == noErr) {
1562 char *certp;
1563 CURLcode result = CopyCertSubject(data, cert, &certp);
1564 if(!result) {
1565 infof(data, "Client certificate: %s\n", certp);
1566 free(certp);
1567 }
1568
1569 CFRelease(cert);
1570 if(result)
1571 return result;
1572 }
1573 certs_c[0] = cert_and_key;
1574 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1575 &kCFTypeArrayCallBacks);
1576 err = SSLSetCertificate(BACKEND->ssl_ctx, certs);
1577 if(certs)
1578 CFRelease(certs);
1579 if(err != noErr) {
1580 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1581 return CURLE_SSL_CERTPROBLEM;
1582 }
1583 CFRelease(cert_and_key);
1584 }
1585 else {
1586 switch(err) {
1587 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1588 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1589 "and its private key.", ssl_cert);
1590 break;
1591 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1592 failf(data, "SSL: Couldn't make sense of the data in the "
1593 "certificate \"%s\" and its private key.",
1594 ssl_cert);
1595 break;
1596 case -25260: /* errSecPassphraseRequired */
1597 failf(data, "SSL The certificate \"%s\" requires a password.",
1598 ssl_cert);
1599 break;
1600 case errSecItemNotFound:
1601 failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1602 "key in the Keychain.", ssl_cert);
1603 break;
1604 default:
1605 failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1606 "key: OSStatus %d", ssl_cert, err);
1607 break;
1608 }
1609 return CURLE_SSL_CERTPROBLEM;
1610 }
1611 }
1612
1613 /* SSL always tries to verify the peer, this only says whether it should
1614 * fail to connect if the verification fails, or if it should continue
1615 * anyway. In the latter case the result of the verification is checked with
1616 * SSL_get_verify_result() below. */
1617#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1618 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1619 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1620 works, it doesn't work as expected under Snow Leopard, Lion or
1621 Mountain Lion.
1622 So we need to call SSLSetEnableCertVerify() on those older cats in order
1623 to disable certificate validation if the user turned that off.
1624 (SecureTransport will always validate the certificate chain by
1625 default.)
1626 Note:
1627 Darwin 11.x.x is Lion (10.7)
1628 Darwin 12.x.x is Mountain Lion (10.8)
1629 Darwin 13.x.x is Mavericks (10.9)
1630 Darwin 14.x.x is Yosemite (10.10)
1631 Darwin 15.x.x is El Capitan (10.11)
1632 */
1633#if CURL_BUILD_MAC
1634 if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
1635#else
1636 if(SSLSetSessionOption != NULL) {
1637#endif /* CURL_BUILD_MAC */
1638 bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
1639 err = SSLSetSessionOption(BACKEND->ssl_ctx,
1640 kSSLSessionOptionBreakOnServerAuth,
1641 break_on_auth);
1642 if(err != noErr) {
1643 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1644 return CURLE_SSL_CONNECT_ERROR;
1645 }
1646 }
1647 else {
1648#if CURL_SUPPORT_MAC_10_8
1649 err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
1650 conn->ssl_config.verifypeer?true:false);
1651 if(err != noErr) {
1652 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1653 return CURLE_SSL_CONNECT_ERROR;
1654 }
1655#endif /* CURL_SUPPORT_MAC_10_8 */
1656 }
1657#else
1658 err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
1659 conn->ssl_config.verifypeer?true:false);
1660 if(err != noErr) {
1661 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1662 return CURLE_SSL_CONNECT_ERROR;
1663 }
1664#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1665
1666 if(ssl_cafile && verifypeer) {
1667 bool is_cert_file = is_file(ssl_cafile);
1668
1669 if(!is_cert_file) {
1670 failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
1671 return CURLE_SSL_CACERT_BADFILE;
1672 }
1673 }
1674
1675 /* Configure hostname check. SNI is used if available.
1676 * Both hostname check and SNI require SSLSetPeerDomainName().
1677 * Also: the verifyhost setting influences SNI usage */
1678 if(conn->ssl_config.verifyhost) {
1679 err = SSLSetPeerDomainName(BACKEND->ssl_ctx, hostname,
1680 strlen(hostname));
1681
1682 if(err != noErr) {
1683 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1684 err);
1685 }
1686
1687 if((Curl_inet_pton(AF_INET, hostname, &addr))
1688 #ifdef ENABLE_IPV6
1689 || (Curl_inet_pton(AF_INET6, hostname, &addr))
1690 #endif
1691 ) {
1692 infof(data, "WARNING: using IP address, SNI is being disabled by "
1693 "the OS.\n");
1694 }
1695 }
1696 else {
1697 infof(data, "WARNING: disabling hostname validation also disables SNI.\n");
1698 }
1699
1700 /* Disable cipher suites that ST supports but are not safe. These ciphers
1701 are unlikely to be used in any case since ST gives other ciphers a much
1702 higher priority, but it's probably better that we not connect at all than
1703 to give the user a false sense of security if the server only supports
1704 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1705 (void)SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count);
1706 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1707 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1708 if(all_ciphers && allowed_ciphers &&
1709 SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers,
1710 &all_ciphers_count) == noErr) {
1711 for(i = 0UL ; i < all_ciphers_count ; i++) {
1712#if CURL_BUILD_MAC
1713 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1714 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1715 Work around the problem here by disabling those ciphers if we are
1716 running in an affected version of OS X. */
1717 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1718 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1719 continue;
1720 }
1721#endif /* CURL_BUILD_MAC */
1722 switch(all_ciphers[i]) {
1723 /* Disable NULL ciphersuites: */
1724 case SSL_NULL_WITH_NULL_NULL:
1725 case SSL_RSA_WITH_NULL_MD5:
1726 case SSL_RSA_WITH_NULL_SHA:
1727 case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1728 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1729 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1730 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1731 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1732 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1733 case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1734 case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1735 case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1736 case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1737 case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1738 case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1739 case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1740 case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1741 case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1742 /* Disable anonymous ciphersuites: */
1743 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1744 case SSL_DH_anon_WITH_RC4_128_MD5:
1745 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1746 case SSL_DH_anon_WITH_DES_CBC_SHA:
1747 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1748 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1749 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1750 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1751 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1752 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1753 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1754 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1755 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1756 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1757 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1758 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1759 /* Disable weak key ciphersuites: */
1760 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1761 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1762 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1763 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1764 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1765 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1766 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1767 case SSL_RSA_WITH_DES_CBC_SHA:
1768 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1769 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1770 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1771 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1772 /* Disable IDEA: */
1773 case SSL_RSA_WITH_IDEA_CBC_SHA:
1774 case SSL_RSA_WITH_IDEA_CBC_MD5:
1775 /* Disable RC4: */
1776 case SSL_RSA_WITH_RC4_128_MD5:
1777 case SSL_RSA_WITH_RC4_128_SHA:
1778 case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
1779 case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/
1780 case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
1781 case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
1782 case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */
1783 case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */
1784 case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */
1785 break;
1786 default: /* enable everything else */
1787 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1788 break;
1789 }
1790 }
1791 err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers,
1792 allowed_ciphers_count);
1793 if(err != noErr) {
1794 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1795 return CURLE_SSL_CONNECT_ERROR;
1796 }
1797 }
1798 else {
1799 Curl_safefree(all_ciphers);
1800 Curl_safefree(allowed_ciphers);
1801 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1802 return CURLE_OUT_OF_MEMORY;
1803 }
1804 Curl_safefree(all_ciphers);
1805 Curl_safefree(allowed_ciphers);
1806
1807#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1808 /* We want to enable 1/n-1 when using a CBC cipher unless the user
1809 specifically doesn't want us doing that: */
1810 if(SSLSetSessionOption != NULL) {
1811 /* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */
1812 SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1813 !data->set.ssl.enable_beast);
1814 SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart,
1815 data->set.ssl.falsestart); /* false start support */
1816 }
1817#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1818
1819 /* Check if there's a cached ID we can/should use here! */
1820 if(SSL_SET_OPTION(primary.sessionid)) {
1821 char *ssl_sessionid;
1822 size_t ssl_sessionid_len;
1823
1824 Curl_ssl_sessionid_lock(conn);
1825 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1826 &ssl_sessionid_len, sockindex)) {
1827 /* we got a session id, use it! */
1828 err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1829 Curl_ssl_sessionid_unlock(conn);
1830 if(err != noErr) {
1831 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1832 return CURLE_SSL_CONNECT_ERROR;
1833 }
1834 /* Informational message */
1835 infof(data, "SSL re-using session ID\n");
1836 }
1837 /* If there isn't one, then let's make one up! This has to be done prior
1838 to starting the handshake. */
1839 else {
1840 CURLcode result;
1841 ssl_sessionid =
1842 aprintf("%s:%d:%d:%s:%hu", ssl_cafile,
1843 verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
1844 ssl_sessionid_len = strlen(ssl_sessionid);
1845
1846 err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1847 if(err != noErr) {
1848 Curl_ssl_sessionid_unlock(conn);
1849 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1850 return CURLE_SSL_CONNECT_ERROR;
1851 }
1852
1853 result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len,
1854 sockindex);
1855 Curl_ssl_sessionid_unlock(conn);
1856 if(result) {
1857 failf(data, "failed to store ssl session");
1858 return result;
1859 }
1860 }
1861 }
1862
1863 err = SSLSetIOFuncs(BACKEND->ssl_ctx, SocketRead, SocketWrite);
1864 if(err != noErr) {
1865 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1866 return CURLE_SSL_CONNECT_ERROR;
1867 }
1868
1869 /* pass the raw socket into the SSL layers */
1870 /* We need to store the FD in a constant memory address, because
1871 * SSLSetConnection() will not copy that address. I've found that
1872 * conn->sock[sockindex] may change on its own. */
1873 BACKEND->ssl_sockfd = sockfd;
1874 err = SSLSetConnection(BACKEND->ssl_ctx, connssl);
1875 if(err != noErr) {
1876 failf(data, "SSL: SSLSetConnection() failed: %d", err);
1877 return CURLE_SSL_CONNECT_ERROR;
1878 }
1879
1880 connssl->connecting_state = ssl_connect_2;
1881 return CURLE_OK;
1882}
1883
1884static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
1885{
1886 char *sep_start, *sep_end, *cert_start, *cert_end;
1887 size_t i, j, err;
1888 size_t len;
1889 unsigned char *b64;
1890
1891 /* Jump through the separators at the beginning of the certificate. */
1892 sep_start = strstr(in, "-----");
1893 if(sep_start == NULL)
1894 return 0;
1895 cert_start = strstr(sep_start + 1, "-----");
1896 if(cert_start == NULL)
1897 return -1;
1898
1899 cert_start += 5;
1900
1901 /* Find separator after the end of the certificate. */
1902 cert_end = strstr(cert_start, "-----");
1903 if(cert_end == NULL)
1904 return -1;
1905
1906 sep_end = strstr(cert_end + 1, "-----");
1907 if(sep_end == NULL)
1908 return -1;
1909 sep_end += 5;
1910
1911 len = cert_end - cert_start;
1912 b64 = malloc(len + 1);
1913 if(!b64)
1914 return -1;
1915
1916 /* Create base64 string without linefeeds. */
1917 for(i = 0, j = 0; i < len; i++) {
1918 if(cert_start[i] != '\r' && cert_start[i] != '\n')
1919 b64[j++] = cert_start[i];
1920 }
1921 b64[j] = '\0';
1922
1923 err = Curl_base64_decode((const char *)b64, out, outlen);
1924 free(b64);
1925 if(err) {
1926 free(*out);
1927 return -1;
1928 }
1929
1930 return sep_end - in;
1931}
1932
1933static int read_cert(const char *file, unsigned char **out, size_t *outlen)
1934{
1935 int fd;
1936 ssize_t n, len = 0, cap = 512;
1937 unsigned char buf[512], *data;
1938
1939 fd = open(file, 0);
1940 if(fd < 0)
1941 return -1;
1942
1943 data = malloc(cap);
1944 if(!data) {
1945 close(fd);
1946 return -1;
1947 }
1948
1949 for(;;) {
1950 n = read(fd, buf, sizeof(buf));
1951 if(n < 0) {
1952 close(fd);
1953 free(data);
1954 return -1;
1955 }
1956 else if(n == 0) {
1957 close(fd);
1958 break;
1959 }
1960
1961 if(len + n >= cap) {
1962 cap *= 2;
1963 data = realloc(data, cap);
1964 if(!data) {
1965 close(fd);
1966 return -1;
1967 }
1968 }
1969
1970 memcpy(data + len, buf, n);
1971 len += n;
1972 }
1973 data[len] = '\0';
1974
1975 *out = data;
1976 *outlen = len;
1977
1978 return 0;
1979}
1980
1981static int sslerr_to_curlerr(struct Curl_easy *data, int err)
1982{
1983 switch(err) {
1984 case errSSLXCertChainInvalid:
1985 failf(data, "SSL certificate problem: Invalid certificate chain");
1986 return CURLE_SSL_CACERT;
1987 case errSSLUnknownRootCert:
1988 failf(data, "SSL certificate problem: Untrusted root certificate");
1989 return CURLE_SSL_CACERT;
1990 case errSSLNoRootCert:
1991 failf(data, "SSL certificate problem: No root certificate");
1992 return CURLE_SSL_CACERT;
1993 case errSSLCertExpired:
1994 failf(data, "SSL certificate problem: Certificate chain had an "
1995 "expired certificate");
1996 return CURLE_SSL_CACERT;
1997 case errSSLBadCert:
1998 failf(data, "SSL certificate problem: Couldn't understand the server "
1999 "certificate format");
2000 return CURLE_SSL_CONNECT_ERROR;
2001 case errSSLHostNameMismatch:
2002 failf(data, "SSL certificate peer hostname mismatch");
2003 return CURLE_PEER_FAILED_VERIFICATION;
2004 default:
2005 failf(data, "SSL unexpected certificate error %d", err);
2006 return CURLE_SSL_CACERT;
2007 }
2008}
2009
2010static int append_cert_to_array(struct Curl_easy *data,
2011 unsigned char *buf, size_t buflen,
2012 CFMutableArrayRef array)
2013{
2014 CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
2015 char *certp;
2016 CURLcode result;
2017 if(!certdata) {
2018 failf(data, "SSL: failed to allocate array for CA certificate");
2019 return CURLE_OUT_OF_MEMORY;
2020 }
2021
2022 SecCertificateRef cacert =
2023 SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
2024 CFRelease(certdata);
2025 if(!cacert) {
2026 failf(data, "SSL: failed to create SecCertificate from CA certificate");
2027 return CURLE_SSL_CACERT;
2028 }
2029
2030 /* Check if cacert is valid. */
2031 result = CopyCertSubject(data, cacert, &certp);
2032 if(result)
2033 return result;
2034 free(certp);
2035
2036 CFArrayAppendValue(array, cacert);
2037 CFRelease(cacert);
2038
2039 return CURLE_OK;
2040}
2041
2042static int verify_cert(const char *cafile, struct Curl_easy *data,
2043 SSLContextRef ctx)
2044{
2045 int n = 0, rc;
2046 long res;
2047 unsigned char *certbuf, *der;
2048 size_t buflen, derlen, offset = 0;
2049
2050 if(read_cert(cafile, &certbuf, &buflen) < 0) {
2051 failf(data, "SSL: failed to read or invalid CA certificate");
2052 return CURLE_SSL_CACERT;
2053 }
2054
2055 /*
2056 * Certbuf now contains the contents of the certificate file, which can be
2057 * - a single DER certificate,
2058 * - a single PEM certificate or
2059 * - a bunch of PEM certificates (certificate bundle).
2060 *
2061 * Go through certbuf, and convert any PEM certificate in it into DER
2062 * format.
2063 */
2064 CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
2065 &kCFTypeArrayCallBacks);
2066 if(array == NULL) {
2067 free(certbuf);
2068 failf(data, "SSL: out of memory creating CA certificate array");
2069 return CURLE_OUT_OF_MEMORY;
2070 }
2071
2072 while(offset < buflen) {
2073 n++;
2074
2075 /*
2076 * Check if the certificate is in PEM format, and convert it to DER. If
2077 * this fails, we assume the certificate is in DER format.
2078 */
2079 res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
2080 if(res < 0) {
2081 free(certbuf);
2082 CFRelease(array);
2083 failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
2084 n, offset);
2085 return CURLE_SSL_CACERT;
2086 }
2087 offset += res;
2088
2089 if(res == 0 && offset == 0) {
2090 /* This is not a PEM file, probably a certificate in DER format. */
2091 rc = append_cert_to_array(data, certbuf, buflen, array);
2092 free(certbuf);
2093 if(rc != CURLE_OK) {
2094 CFRelease(array);
2095 return rc;
2096 }
2097 break;
2098 }
2099 else if(res == 0) {
2100 /* No more certificates in the bundle. */
2101 free(certbuf);
2102 break;
2103 }
2104
2105 rc = append_cert_to_array(data, der, derlen, array);
2106 free(der);
2107 if(rc != CURLE_OK) {
2108 free(certbuf);
2109 CFRelease(array);
2110 return rc;
2111 }
2112 }
2113
2114 SecTrustRef trust;
2115 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2116 if(trust == NULL) {
2117 failf(data, "SSL: error getting certificate chain");
2118 CFRelease(array);
2119 return CURLE_OUT_OF_MEMORY;
2120 }
2121 else if(ret != noErr) {
2122 CFRelease(array);
2123 return sslerr_to_curlerr(data, ret);
2124 }
2125
2126 ret = SecTrustSetAnchorCertificates(trust, array);
2127 if(ret != noErr) {
2128 CFRelease(trust);
2129 return sslerr_to_curlerr(data, ret);
2130 }
2131 ret = SecTrustSetAnchorCertificatesOnly(trust, true);
2132 if(ret != noErr) {
2133 CFRelease(trust);
2134 return sslerr_to_curlerr(data, ret);
2135 }
2136
2137 SecTrustResultType trust_eval = 0;
2138 ret = SecTrustEvaluate(trust, &trust_eval);
2139 CFRelease(array);
2140 CFRelease(trust);
2141 if(ret != noErr) {
2142 return sslerr_to_curlerr(data, ret);
2143 }
2144
2145 switch(trust_eval) {
2146 case kSecTrustResultUnspecified:
2147 case kSecTrustResultProceed:
2148 return CURLE_OK;
2149
2150 case kSecTrustResultRecoverableTrustFailure:
2151 case kSecTrustResultDeny:
2152 default:
2153 failf(data, "SSL: certificate verification failed (result: %d)",
2154 trust_eval);
2155 return CURLE_PEER_FAILED_VERIFICATION;
2156 }
2157}
2158
2159#ifdef DARWIN_SSL_PINNEDPUBKEY
2160static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
2161 SSLContextRef ctx,
2162 const char *pinnedpubkey)
2163{ /* Scratch */
2164 size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24;
2165 unsigned char *pubkey = NULL, *realpubkey = NULL;
2166 const unsigned char *spkiHeader = NULL;
2167 CFDataRef publicKeyBits = NULL;
2168
2169 /* Result is returned to caller */
2170 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
2171
2172 /* if a path wasn't specified, don't pin */
2173 if(!pinnedpubkey)
2174 return CURLE_OK;
2175
2176
2177 if(!ctx)
2178 return result;
2179
2180 do {
2181 SecTrustRef trust;
2182 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2183 if(ret != noErr || trust == NULL)
2184 break;
2185
2186 SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
2187 CFRelease(trust);
2188 if(keyRef == NULL)
2189 break;
2190
2191#ifdef DARWIN_SSL_PINNEDPUBKEY_V1
2192
2193 publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL);
2194 CFRelease(keyRef);
2195 if(publicKeyBits == NULL)
2196 break;
2197
2198#elif DARWIN_SSL_PINNEDPUBKEY_V2
2199
2200 OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL,
2201 &publicKeyBits);
2202 CFRelease(keyRef);
2203 if(success != errSecSuccess || publicKeyBits == NULL)
2204 break;
2205
2206#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
2207
2208 pubkeylen = CFDataGetLength(publicKeyBits);
2209 pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits);
2210
2211 switch(pubkeylen) {
2212 case 526:
2213 /* 4096 bit RSA pubkeylen == 526 */
2214 spkiHeader = rsa4096SpkiHeader;
2215 break;
2216 case 270:
2217 /* 2048 bit RSA pubkeylen == 270 */
2218 spkiHeader = rsa2048SpkiHeader;
2219 break;
2220#ifdef DARWIN_SSL_PINNEDPUBKEY_V1
2221 case 65:
2222 /* ecDSA secp256r1 pubkeylen == 65 */
2223 spkiHeader = ecDsaSecp256r1SpkiHeader;
2224 spkiHeaderLength = 26;
2225 break;
2226 case 97:
2227 /* ecDSA secp384r1 pubkeylen == 97 */
2228 spkiHeader = ecDsaSecp384r1SpkiHeader;
2229 spkiHeaderLength = 23;
2230 break;
2231 default:
2232 infof(data, "SSL: unhandled public key length: %d\n", pubkeylen);
2233#elif DARWIN_SSL_PINNEDPUBKEY_V2
2234 default:
2235 /* ecDSA secp256r1 pubkeylen == 91 header already included?
2236 * ecDSA secp384r1 header already included too
2237 * we assume rest of algorithms do same, so do nothing
2238 */
2239 result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey,
2240 pubkeylen);
2241#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
2242 continue; /* break from loop */
2243 }
2244
2245 realpubkeylen = pubkeylen + spkiHeaderLength;
2246 realpubkey = malloc(realpubkeylen);
2247 if(!realpubkey)
2248 break;
2249
2250 memcpy(realpubkey, spkiHeader, spkiHeaderLength);
2251 memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen);
2252
2253 result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey,
2254 realpubkeylen);
2255
2256 } while(0);
2257
2258 Curl_safefree(realpubkey);
2259 if(publicKeyBits != NULL)
2260 CFRelease(publicKeyBits);
2261
2262 return result;
2263}
2264#endif /* DARWIN_SSL_PINNEDPUBKEY */
2265
2266static CURLcode
2267darwinssl_connect_step2(struct connectdata *conn, int sockindex)
2268{
2269 struct Curl_easy *data = conn->data;
2270 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2271 OSStatus err;
2272 SSLCipherSuite cipher;
2273 SSLProtocol protocol = 0;
2274 const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
2275 conn->host.name;
2276
2277 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
2278 || ssl_connect_2_reading == connssl->connecting_state
2279 || ssl_connect_2_writing == connssl->connecting_state);
2280
2281 /* Here goes nothing: */
2282 err = SSLHandshake(BACKEND->ssl_ctx);
2283
2284 if(err != noErr) {
2285 switch(err) {
2286 case errSSLWouldBlock: /* they're not done with us yet */
2287 connssl->connecting_state = BACKEND->ssl_direction ?
2288 ssl_connect_2_writing : ssl_connect_2_reading;
2289 return CURLE_OK;
2290
2291 /* The below is errSSLServerAuthCompleted; it's not defined in
2292 Leopard's headers */
2293 case -9841:
2294 if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
2295 int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
2296 BACKEND->ssl_ctx);
2297 if(res != CURLE_OK)
2298 return res;
2299 }
2300 /* the documentation says we need to call SSLHandshake() again */
2301 return darwinssl_connect_step2(conn, sockindex);
2302
2303 /* These are all certificate problems with the server: */
2304 case errSSLXCertChainInvalid:
2305 failf(data, "SSL certificate problem: Invalid certificate chain");
2306 return CURLE_SSL_CACERT;
2307 case errSSLUnknownRootCert:
2308 failf(data, "SSL certificate problem: Untrusted root certificate");
2309 return CURLE_SSL_CACERT;
2310 case errSSLNoRootCert:
2311 failf(data, "SSL certificate problem: No root certificate");
2312 return CURLE_SSL_CACERT;
2313 case errSSLCertExpired:
2314 failf(data, "SSL certificate problem: Certificate chain had an "
2315 "expired certificate");
2316 return CURLE_SSL_CACERT;
2317 case errSSLBadCert:
2318 failf(data, "SSL certificate problem: Couldn't understand the server "
2319 "certificate format");
2320 return CURLE_SSL_CONNECT_ERROR;
2321
2322 /* These are all certificate problems with the client: */
2323 case errSecAuthFailed:
2324 failf(data, "SSL authentication failed");
2325 return CURLE_SSL_CONNECT_ERROR;
2326 case errSSLPeerHandshakeFail:
2327 failf(data, "SSL peer handshake failed, the server most likely "
2328 "requires a client certificate to connect");
2329 return CURLE_SSL_CONNECT_ERROR;
2330 case errSSLPeerUnknownCA:
2331 failf(data, "SSL server rejected the client certificate due to "
2332 "the certificate being signed by an unknown certificate "
2333 "authority");
2334 return CURLE_SSL_CONNECT_ERROR;
2335
2336 /* This error is raised if the server's cert didn't match the server's
2337 host name: */
2338 case errSSLHostNameMismatch:
2339 failf(data, "SSL certificate peer verification failed, the "
2340 "certificate did not match \"%s\"\n", conn->host.dispname);
2341 return CURLE_PEER_FAILED_VERIFICATION;
2342
2343 /* Generic handshake errors: */
2344 case errSSLConnectionRefused:
2345 failf(data, "Server dropped the connection during the SSL handshake");
2346 return CURLE_SSL_CONNECT_ERROR;
2347 case errSSLClosedAbort:
2348 failf(data, "Server aborted the SSL handshake");
2349 return CURLE_SSL_CONNECT_ERROR;
2350 case errSSLNegotiation:
2351 failf(data, "Could not negotiate an SSL cipher suite with the server");
2352 return CURLE_SSL_CONNECT_ERROR;
2353 /* Sometimes paramErr happens with buggy ciphers: */
2354 case paramErr: case errSSLInternal:
2355 failf(data, "Internal SSL engine error encountered during the "
2356 "SSL handshake");
2357 return CURLE_SSL_CONNECT_ERROR;
2358 case errSSLFatalAlert:
2359 failf(data, "Fatal SSL engine error encountered during the SSL "
2360 "handshake");
2361 return CURLE_SSL_CONNECT_ERROR;
2362 default:
2363 failf(data, "Unknown SSL protocol error in connection to %s:%d",
2364 hostname, err);
2365 return CURLE_SSL_CONNECT_ERROR;
2366 }
2367 }
2368 else {
2369 /* we have been connected fine, we're not waiting for anything else. */
2370 connssl->connecting_state = ssl_connect_3;
2371
2372#ifdef DARWIN_SSL_PINNEDPUBKEY
2373 if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
2374 CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
2375 data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
2376 if(result) {
2377 failf(data, "SSL: public key does not match pinned public key!");
2378 return result;
2379 }
2380 }
2381#endif /* DARWIN_SSL_PINNEDPUBKEY */
2382
2383 /* Informational message */
2384 (void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher);
2385 (void)SSLGetNegotiatedProtocolVersion(BACKEND->ssl_ctx, &protocol);
2386 switch(protocol) {
2387 case kSSLProtocol2:
2388 infof(data, "SSL 2.0 connection using %s\n",
2389 SSLCipherNameForNumber(cipher));
2390 break;
2391 case kSSLProtocol3:
2392 infof(data, "SSL 3.0 connection using %s\n",
2393 SSLCipherNameForNumber(cipher));
2394 break;
2395 case kTLSProtocol1:
2396 infof(data, "TLS 1.0 connection using %s\n",
2397 TLSCipherNameForNumber(cipher));
2398 break;
2399#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2400 case kTLSProtocol11:
2401 infof(data, "TLS 1.1 connection using %s\n",
2402 TLSCipherNameForNumber(cipher));
2403 break;
2404 case kTLSProtocol12:
2405 infof(data, "TLS 1.2 connection using %s\n",
2406 TLSCipherNameForNumber(cipher));
2407 break;
2408#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2409#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
2410 case kTLSProtocol13:
2411 infof(data, "TLS 1.3 connection using %s\n",
2412 TLSCipherNameForNumber(cipher));
2413 break;
2414#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
2415 default:
2416 infof(data, "Unknown protocol connection\n");
2417 break;
2418 }
2419
2420 return CURLE_OK;
2421 }
2422}
2423
2424#ifndef CURL_DISABLE_VERBOSE_STRINGS
2425/* This should be called during step3 of the connection at the earliest */
2426static void
2427show_verbose_server_cert(struct connectdata *conn,
2428 int sockindex)
2429{
2430 struct Curl_easy *data = conn->data;
2431 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2432 CFArrayRef server_certs = NULL;
2433 SecCertificateRef server_cert;
2434 OSStatus err;
2435 CFIndex i, count;
2436 SecTrustRef trust = NULL;
2437
2438 if(!BACKEND->ssl_ctx)
2439 return;
2440
2441#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
2442#if CURL_BUILD_IOS
2443#pragma unused(server_certs)
2444 err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
2445 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2446 a null trust, so be on guard for that: */
2447 if(err == noErr && trust) {
2448 count = SecTrustGetCertificateCount(trust);
2449 for(i = 0L ; i < count ; i++) {
2450 CURLcode result;
2451 char *certp;
2452 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2453 result = CopyCertSubject(data, server_cert, &certp);
2454 if(!result) {
2455 infof(data, "Server certificate: %s\n", certp);
2456 free(certp);
2457 }
2458 }
2459 CFRelease(trust);
2460 }
2461#else
2462 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
2463 The function SecTrustGetCertificateAtIndex() is officially present
2464 in Lion, but it is unfortunately also present in Snow Leopard as
2465 private API and doesn't work as expected. So we have to look for
2466 a different symbol to make sure this code is only executed under
2467 Lion or later. */
2468 if(SecTrustEvaluateAsync != NULL) {
2469#pragma unused(server_certs)
2470 err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
2471 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2472 a null trust, so be on guard for that: */
2473 if(err == noErr && trust) {
2474 count = SecTrustGetCertificateCount(trust);
2475 for(i = 0L ; i < count ; i++) {
2476 char *certp;
2477 CURLcode result;
2478 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2479 result = CopyCertSubject(data, server_cert, &certp);
2480 if(!result) {
2481 infof(data, "Server certificate: %s\n", certp);
2482 free(certp);
2483 }
2484 }
2485 CFRelease(trust);
2486 }
2487 }
2488 else {
2489#if CURL_SUPPORT_MAC_10_8
2490 err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
2491 /* Just in case SSLCopyPeerCertificates() returns null too... */
2492 if(err == noErr && server_certs) {
2493 count = CFArrayGetCount(server_certs);
2494 for(i = 0L ; i < count ; i++) {
2495 char *certp;
2496 CURLcode result;
2497 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
2498 i);
2499 result = CopyCertSubject(data, server_cert, &certp);
2500 if(!result) {
2501 infof(data, "Server certificate: %s\n", certp);
2502 free(certp);
2503 }
2504 }
2505 CFRelease(server_certs);
2506 }
2507#endif /* CURL_SUPPORT_MAC_10_8 */
2508 }
2509#endif /* CURL_BUILD_IOS */
2510#else
2511#pragma unused(trust)
2512 err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
2513 if(err == noErr) {
2514 count = CFArrayGetCount(server_certs);
2515 for(i = 0L ; i < count ; i++) {
2516 CURLcode result;
2517 char *certp;
2518 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
2519 result = CopyCertSubject(data, server_cert, &certp);
2520 if(!result) {
2521 infof(data, "Server certificate: %s\n", certp);
2522 free(certp);
2523 }
2524 }
2525 CFRelease(server_certs);
2526 }
2527#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
2528}
2529#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
2530
2531static CURLcode
2532darwinssl_connect_step3(struct connectdata *conn,
2533 int sockindex)
2534{
2535 struct Curl_easy *data = conn->data;
2536 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2537
2538 /* There is no step 3!
2539 * Well, okay, if verbose mode is on, let's print the details of the
2540 * server certificates. */
2541#ifndef CURL_DISABLE_VERBOSE_STRINGS
2542 if(data->set.verbose)
2543 show_verbose_server_cert(conn, sockindex);
2544#endif
2545
2546 connssl->connecting_state = ssl_connect_done;
2547 return CURLE_OK;
2548}
2549
2550static Curl_recv darwinssl_recv;
2551static Curl_send darwinssl_send;
2552
2553static CURLcode
2554darwinssl_connect_common(struct connectdata *conn,
2555 int sockindex,
2556 bool nonblocking,
2557 bool *done)
2558{
2559 CURLcode result;
2560 struct Curl_easy *data = conn->data;
2561 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2562 curl_socket_t sockfd = conn->sock[sockindex];
2563 long timeout_ms;
2564 int what;
2565
2566 /* check if the connection has already been established */
2567 if(ssl_connection_complete == connssl->state) {
2568 *done = TRUE;
2569 return CURLE_OK;
2570 }
2571
2572 if(ssl_connect_1 == connssl->connecting_state) {
2573 /* Find out how much more time we're allowed */
2574 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2575
2576 if(timeout_ms < 0) {
2577 /* no need to continue if time already is up */
2578 failf(data, "SSL connection timeout");
2579 return CURLE_OPERATION_TIMEDOUT;
2580 }
2581
2582 result = darwinssl_connect_step1(conn, sockindex);
2583 if(result)
2584 return result;
2585 }
2586
2587 while(ssl_connect_2 == connssl->connecting_state ||
2588 ssl_connect_2_reading == connssl->connecting_state ||
2589 ssl_connect_2_writing == connssl->connecting_state) {
2590
2591 /* check allowed time left */
2592 timeout_ms = Curl_timeleft(data, NULL, TRUE);
2593
2594 if(timeout_ms < 0) {
2595 /* no need to continue if time already is up */
2596 failf(data, "SSL connection timeout");
2597 return CURLE_OPERATION_TIMEDOUT;
2598 }
2599
2600 /* if ssl is expecting something, check if it's available. */
2601 if(connssl->connecting_state == ssl_connect_2_reading ||
2602 connssl->connecting_state == ssl_connect_2_writing) {
2603
2604 curl_socket_t writefd = ssl_connect_2_writing ==
2605 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2606 curl_socket_t readfd = ssl_connect_2_reading ==
2607 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2608
2609 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
2610 nonblocking?0:timeout_ms);
2611 if(what < 0) {
2612 /* fatal error */
2613 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2614 return CURLE_SSL_CONNECT_ERROR;
2615 }
2616 else if(0 == what) {
2617 if(nonblocking) {
2618 *done = FALSE;
2619 return CURLE_OK;
2620 }
2621 else {
2622 /* timeout */
2623 failf(data, "SSL connection timeout");
2624 return CURLE_OPERATION_TIMEDOUT;
2625 }
2626 }
2627 /* socket is readable or writable */
2628 }
2629
2630 /* Run transaction, and return to the caller if it failed or if this
2631 * connection is done nonblocking and this loop would execute again. This
2632 * permits the owner of a multi handle to abort a connection attempt
2633 * before step2 has completed while ensuring that a client using select()
2634 * or epoll() will always have a valid fdset to wait on.
2635 */
2636 result = darwinssl_connect_step2(conn, sockindex);
2637 if(result || (nonblocking &&
2638 (ssl_connect_2 == connssl->connecting_state ||
2639 ssl_connect_2_reading == connssl->connecting_state ||
2640 ssl_connect_2_writing == connssl->connecting_state)))
2641 return result;
2642
2643 } /* repeat step2 until all transactions are done. */
2644
2645
2646 if(ssl_connect_3 == connssl->connecting_state) {
2647 result = darwinssl_connect_step3(conn, sockindex);
2648 if(result)
2649 return result;
2650 }
2651
2652 if(ssl_connect_done == connssl->connecting_state) {
2653 connssl->state = ssl_connection_complete;
2654 conn->recv[sockindex] = darwinssl_recv;
2655 conn->send[sockindex] = darwinssl_send;
2656 *done = TRUE;
2657 }
2658 else
2659 *done = FALSE;
2660
2661 /* Reset our connect state machine */
2662 connssl->connecting_state = ssl_connect_1;
2663
2664 return CURLE_OK;
2665}
2666
2667static CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
2668 int sockindex, bool *done)
2669{
2670 return darwinssl_connect_common(conn, sockindex, TRUE, done);
2671}
2672
2673static CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex)
2674{
2675 CURLcode result;
2676 bool done = FALSE;
2677
2678 result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
2679
2680 if(result)
2681 return result;
2682
2683 DEBUGASSERT(done);
2684
2685 return CURLE_OK;
2686}
2687
2688static void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
2689{
2690 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2691
2692 if(BACKEND->ssl_ctx) {
2693 (void)SSLClose(BACKEND->ssl_ctx);
2694#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2695 if(SSLCreateContext != NULL)
2696 CFRelease(BACKEND->ssl_ctx);
2697#if CURL_SUPPORT_MAC_10_8
2698 else
2699 (void)SSLDisposeContext(BACKEND->ssl_ctx);
2700#endif /* CURL_SUPPORT_MAC_10_8 */
2701#else
2702 (void)SSLDisposeContext(BACKEND->ssl_ctx);
2703#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2704 BACKEND->ssl_ctx = NULL;
2705 }
2706 BACKEND->ssl_sockfd = 0;
2707}
2708
2709static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
2710{
2711 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2712 struct Curl_easy *data = conn->data;
2713 ssize_t nread;
2714 int what;
2715 int rc;
2716 char buf[120];
2717
2718 if(!BACKEND->ssl_ctx)
2719 return 0;
2720
2721 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
2722 return 0;
2723
2724 Curl_darwinssl_close(conn, sockindex);
2725
2726 rc = 0;
2727
2728 what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
2729
2730 for(;;) {
2731 if(what < 0) {
2732 /* anything that gets here is fatally bad */
2733 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2734 rc = -1;
2735 break;
2736 }
2737
2738 if(!what) { /* timeout */
2739 failf(data, "SSL shutdown timeout");
2740 break;
2741 }
2742
2743 /* Something to read, let's do it and hope that it is the close
2744 notify alert from the server. No way to SSL_Read now, so use read(). */
2745
2746 nread = read(conn->sock[sockindex], buf, sizeof(buf));
2747
2748 if(nread < 0) {
2749 failf(data, "read: %s", strerror(errno));
2750 rc = -1;
2751 }
2752
2753 if(nread <= 0)
2754 break;
2755
2756 what = SOCKET_READABLE(conn->sock[sockindex], 0);
2757 }
2758
2759 return rc;
2760}
2761
2762static void Curl_darwinssl_session_free(void *ptr)
2763{
2764 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
2765 cached session ID inside the Security framework. There is a private
2766 function that does this, but I don't want to have to explain to you why I
2767 got your application rejected from the App Store due to the use of a
2768 private API, so the best we can do is free up our own char array that we
2769 created way back in darwinssl_connect_step1... */
2770 Curl_safefree(ptr);
2771}
2772
2773static size_t Curl_darwinssl_version(char *buffer, size_t size)
2774{
2775 return snprintf(buffer, size, "SecureTransport");
2776}
2777
2778/*
2779 * This function uses SSLGetSessionState to determine connection status.
2780 *
2781 * Return codes:
2782 * 1 means the connection is still in place
2783 * 0 means the connection has been closed
2784 * -1 means the connection status is unknown
2785 */
2786static int Curl_darwinssl_check_cxn(struct connectdata *conn)
2787{
2788 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2789 OSStatus err;
2790 SSLSessionState state;
2791
2792 if(BACKEND->ssl_ctx) {
2793 err = SSLGetSessionState(BACKEND->ssl_ctx, &state);
2794 if(err == noErr)
2795 return state == kSSLConnected || state == kSSLHandshake;
2796 return -1;
2797 }
2798 return 0;
2799}
2800
2801static bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2802 int connindex)
2803{
2804 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2805 OSStatus err;
2806 size_t buffer;
2807
2808 if(BACKEND->ssl_ctx) { /* SSL is in use */
2809 err = SSLGetBufferedReadSize(BACKEND->ssl_ctx, &buffer);
2810 if(err == noErr)
2811 return buffer > 0UL;
2812 return false;
2813 }
2814 else
2815 return false;
2816}
2817
2818static CURLcode Curl_darwinssl_random(struct Curl_easy *data UNUSED_PARAM,
2819 unsigned char *entropy, size_t length)
2820{
2821 /* arc4random_buf() isn't available on cats older than Lion, so let's
2822 do this manually for the benefit of the older cats. */
2823 size_t i;
2824 u_int32_t random_number = 0;
2825
2826 (void)data;
2827
2828 for(i = 0 ; i < length ; i++) {
2829 if(i % sizeof(u_int32_t) == 0)
2830 random_number = arc4random();
2831 entropy[i] = random_number & 0xFF;
2832 random_number >>= 8;
2833 }
2834 i = random_number = 0;
2835 return CURLE_OK;
2836}
2837
2838static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2839 size_t tmplen,
2840 unsigned char *md5sum, /* output */
2841 size_t md5len)
2842{
2843 (void)md5len;
2844 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2845 return CURLE_OK;
2846}
2847
2848static void Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */
2849 size_t tmplen,
2850 unsigned char *sha256sum, /* output */
2851 size_t sha256len)
2852{
2853 assert(sha256len >= CURL_SHA256_DIGEST_LENGTH);
2854 (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum);
2855}
2856
2857static bool Curl_darwinssl_false_start(void)
2858{
2859#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
2860 if(SSLSetSessionOption != NULL)
2861 return TRUE;
2862#endif
2863 return FALSE;
2864}
2865
2866static ssize_t darwinssl_send(struct connectdata *conn,
2867 int sockindex,
2868 const void *mem,
2869 size_t len,
2870 CURLcode *curlcode)
2871{
2872 /*struct Curl_easy *data = conn->data;*/
2873 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2874 size_t processed = 0UL;
2875 OSStatus err;
2876
2877 /* The SSLWrite() function works a little differently than expected. The
2878 fourth argument (processed) is currently documented in Apple's
2879 documentation as: "On return, the length, in bytes, of the data actually
2880 written."
2881
2882 Now, one could interpret that as "written to the socket," but actually,
2883 it returns the amount of data that was written to a buffer internal to
2884 the SSLContextRef instead. So it's possible for SSLWrite() to return
2885 errSSLWouldBlock and a number of bytes "written" because those bytes were
2886 encrypted and written to a buffer, not to the socket.
2887
2888 So if this happens, then we need to keep calling SSLWrite() over and
2889 over again with no new data until it quits returning errSSLWouldBlock. */
2890
2891 /* Do we have buffered data to write from the last time we were called? */
2892 if(BACKEND->ssl_write_buffered_length) {
2893 /* Write the buffered data: */
2894 err = SSLWrite(BACKEND->ssl_ctx, NULL, 0UL, &processed);
2895 switch(err) {
2896 case noErr:
2897 /* processed is always going to be 0 because we didn't write to
2898 the buffer, so return how much was written to the socket */
2899 processed = BACKEND->ssl_write_buffered_length;
2900 BACKEND->ssl_write_buffered_length = 0UL;
2901 break;
2902 case errSSLWouldBlock: /* argh, try again */
2903 *curlcode = CURLE_AGAIN;
2904 return -1L;
2905 default:
2906 failf(conn->data, "SSLWrite() returned error %d", err);
2907 *curlcode = CURLE_SEND_ERROR;
2908 return -1L;
2909 }
2910 }
2911 else {
2912 /* We've got new data to write: */
2913 err = SSLWrite(BACKEND->ssl_ctx, mem, len, &processed);
2914 if(err != noErr) {
2915 switch(err) {
2916 case errSSLWouldBlock:
2917 /* Data was buffered but not sent, we have to tell the caller
2918 to try sending again, and remember how much was buffered */
2919 BACKEND->ssl_write_buffered_length = len;
2920 *curlcode = CURLE_AGAIN;
2921 return -1L;
2922 default:
2923 failf(conn->data, "SSLWrite() returned error %d", err);
2924 *curlcode = CURLE_SEND_ERROR;
2925 return -1L;
2926 }
2927 }
2928 }
2929 return (ssize_t)processed;
2930}
2931
2932static ssize_t darwinssl_recv(struct connectdata *conn,
2933 int num,
2934 char *buf,
2935 size_t buffersize,
2936 CURLcode *curlcode)
2937{
2938 /*struct Curl_easy *data = conn->data;*/
2939 struct ssl_connect_data *connssl = &conn->ssl[num];
2940 size_t processed = 0UL;
2941 OSStatus err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed);
2942
2943 if(err != noErr) {
2944 switch(err) {
2945 case errSSLWouldBlock: /* return how much we read (if anything) */
2946 if(processed)
2947 return (ssize_t)processed;
2948 *curlcode = CURLE_AGAIN;
2949 return -1L;
2950 break;
2951
2952 /* errSSLClosedGraceful - server gracefully shut down the SSL session
2953 errSSLClosedNoNotify - server hung up on us instead of sending a
2954 closure alert notice, read() is returning 0
2955 Either way, inform the caller that the server disconnected. */
2956 case errSSLClosedGraceful:
2957 case errSSLClosedNoNotify:
2958 *curlcode = CURLE_OK;
2959 return -1L;
2960 break;
2961
2962 default:
2963 failf(conn->data, "SSLRead() return error %d", err);
2964 *curlcode = CURLE_RECV_ERROR;
2965 return -1L;
2966 break;
2967 }
2968 }
2969 return (ssize_t)processed;
2970}
2971
2972static void *Curl_darwinssl_get_internals(struct ssl_connect_data *connssl,
2973 CURLINFO info UNUSED_PARAM)
2974{
2975 (void)info;
2976 return BACKEND->ssl_ctx;
2977}
2978
2979const struct Curl_ssl Curl_ssl_darwinssl = {
2980 { CURLSSLBACKEND_DARWINSSL, "darwinssl" }, /* info */
2981
2982 0, /* have_ca_path */
2983 0, /* have_certinfo */
2984#ifdef DARWIN_SSL_PINNEDPUBKEY
2985 1, /* have_pinnedpubkey */
2986#else
2987 0, /* have_pinnedpubkey */
2988#endif /* DARWIN_SSL_PINNEDPUBKEY */
2989 0, /* have_ssl_ctx */
2990 0, /* support_https_proxy */
2991
2992 sizeof(struct ssl_backend_data),
2993
2994 Curl_none_init, /* init */
2995 Curl_none_cleanup, /* cleanup */
2996 Curl_darwinssl_version, /* version */
2997 Curl_darwinssl_check_cxn, /* check_cxn */
2998 Curl_darwinssl_shutdown, /* shutdown */
2999 Curl_darwinssl_data_pending, /* data_pending */
3000 Curl_darwinssl_random, /* random */
3001 Curl_none_cert_status_request, /* cert_status_request */
3002 Curl_darwinssl_connect, /* connect */
3003 Curl_darwinssl_connect_nonblocking, /* connect_nonblocking */
3004 Curl_darwinssl_get_internals, /* get_internals */
3005 Curl_darwinssl_close, /* close_one */
3006 Curl_none_close_all, /* close_all */
3007 Curl_darwinssl_session_free, /* session_free */
3008 Curl_none_set_engine, /* set_engine */
3009 Curl_none_set_engine_default, /* set_engine_default */
3010 Curl_none_engines_list, /* engines_list */
3011 Curl_darwinssl_false_start, /* false_start */
3012 Curl_darwinssl_md5sum, /* md5sum */
3013 Curl_darwinssl_sha256sum /* sha256sum */
3014};
3015
3016#ifdef __clang__
3017#pragma clang diagnostic pop
3018#endif
3019
3020#endif /* USE_DARWINSSL */
Note: See TracBrowser for help on using the repository browser.