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