1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
9 * Copyright (C) 2012 - 2020, 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
134 struct 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 /* pinned public key support tests */
142
143 /* version 1 supports macOS 10.12+ and iOS 10+ */
144 #if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \
145 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200))
146 #define SECTRANSP_PINNEDPUBKEY_V1 1
147 #endif
148
149 /* version 2 supports MacOSX 10.7+ */
150 #if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
151 #define SECTRANSP_PINNEDPUBKEY_V2 1
152 #endif
153
154 #if defined(SECTRANSP_PINNEDPUBKEY_V1) || defined(SECTRANSP_PINNEDPUBKEY_V2)
155 /* this backend supports CURLOPT_PINNEDPUBLICKEY */
156 #define SECTRANSP_PINNEDPUBKEY 1
157 #endif /* SECTRANSP_PINNEDPUBKEY */
158
159 #ifdef SECTRANSP_PINNEDPUBKEY
160 /* both new and old APIs return rsa keys missing the spki header (not DER) */
161 static const unsigned char rsa4096SpkiHeader[] = {
162 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d,
163 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
164 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
165 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00};
166
167 static const unsigned char rsa2048SpkiHeader[] = {
168 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
169 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
170 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
171 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00};
172 #ifdef SECTRANSP_PINNEDPUBKEY_V1
173 /* the *new* version doesn't return DER encoded ecdsa certs like the old... */
174 static const unsigned char ecDsaSecp256r1SpkiHeader[] = {
175 0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
176 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
177 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48,
178 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
179 0x42, 0x00};
180
181 static const unsigned char ecDsaSecp384r1SpkiHeader[] = {
182 0x30, 0x76, 0x30, 0x10, 0x06, 0x07,
183 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
184 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04,
185 0x00, 0x22, 0x03, 0x62, 0x00};
186 #endif /* SECTRANSP_PINNEDPUBKEY_V1 */
187 #endif /* SECTRANSP_PINNEDPUBKEY */
188
189 /* The following two functions were ripped from Apple sample code,
190 * with some modifications: */
SocketRead(SSLConnectionRef connection,void * data,size_t * dataLength)191 static OSStatus SocketRead(SSLConnectionRef connection,
192 void *data, /* owned by
193 * caller, data
194 * RETURNED */
195 size_t *dataLength) /* IN/OUT */
196 {
197 size_t bytesToGo = *dataLength;
198 size_t initLen = bytesToGo;
199 UInt8 *currData = (UInt8 *)data;
200 /*int sock = *(int *)connection;*/
201 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
202 struct ssl_backend_data *backend = connssl->backend;
203 int sock = backend->ssl_sockfd;
204 OSStatus rtn = noErr;
205 size_t bytesRead;
206 ssize_t rrtn;
207 int theErr;
208
209 *dataLength = 0;
210
211 for(;;) {
212 bytesRead = 0;
213 rrtn = read(sock, currData, bytesToGo);
214 if(rrtn <= 0) {
215 /* this is guesswork... */
216 theErr = errno;
217 if(rrtn == 0) { /* EOF = server hung up */
218 /* the framework will turn this into errSSLClosedNoNotify */
219 rtn = errSSLClosedGraceful;
220 }
221 else /* do the switch */
222 switch(theErr) {
223 case ENOENT:
224 /* connection closed */
225 rtn = errSSLClosedGraceful;
226 break;
227 case ECONNRESET:
228 rtn = errSSLClosedAbort;
229 break;
230 case EAGAIN:
231 rtn = errSSLWouldBlock;
232 backend->ssl_direction = false;
233 break;
234 default:
235 rtn = ioErr;
236 break;
237 }
238 break;
239 }
240 else {
241 bytesRead = rrtn;
242 }
243 bytesToGo -= bytesRead;
244 currData += bytesRead;
245
246 if(bytesToGo == 0) {
247 /* filled buffer with incoming data, done */
248 break;
249 }
250 }
251 *dataLength = initLen - bytesToGo;
252
253 return rtn;
254 }
255
SocketWrite(SSLConnectionRef connection,const void * data,size_t * dataLength)256 static OSStatus SocketWrite(SSLConnectionRef connection,
257 const void *data,
258 size_t *dataLength) /* IN/OUT */
259 {
260 size_t bytesSent = 0;
261 /*int sock = *(int *)connection;*/
262 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
263 struct ssl_backend_data *backend = connssl->backend;
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
SSLCipherNameForNumber(SSLCipherSuite cipher)298 CF_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
TLSCipherNameForNumber(SSLCipherSuite cipher)444 CF_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
GetDarwinVersionNumber(int * major,int * minor)882 CF_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. */
getsubject(SecCertificateRef cert)916 CF_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
CopyCertSubject(struct Curl_easy * data,SecCertificateRef cert,char ** certp)943 static 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: */
CopyIdentityWithLabelOldSchool(char * label,SecIdentityRef * out_c_a_k)994 static 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
CopyIdentityWithLabel(char * label,SecIdentityRef * out_cert_and_key)1033 static 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
CopyIdentityFromPKCS12File(const char * cPath,const struct curl_blob * blob,const char * cPassword,SecIdentityRef * out_cert_and_key)1128 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
1129 const struct curl_blob *blob,
1130 const char *cPassword,
1131 SecIdentityRef *out_cert_and_key)
1132 {
1133 OSStatus status = errSecItemNotFound;
1134 CFURLRef pkcs_url = NULL;
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 bool resource_imported;
1144
1145 if(blob) {
1146 pkcs_data = CFDataCreate(kCFAllocatorDefault,
1147 (const unsigned char *)blob->data, blob->len);
1148 status = (pkcs_data != NULL) ? errSecSuccess : errSecAllocate;
1149 resource_imported = (pkcs_data != NULL);
1150 }
1151 else {
1152 pkcs_url =
1153 CFURLCreateFromFileSystemRepresentation(NULL,
1154 (const UInt8 *)cPath,
1155 strlen(cPath), false);
1156 resource_imported =
1157 CFURLCreateDataAndPropertiesFromResource(NULL,
1158 pkcs_url, &pkcs_data,
1159 NULL, NULL, &status);
1160 }
1161
1162 if(resource_imported) {
1163 CFArrayRef items = NULL;
1164
1165 /* On iOS SecPKCS12Import will never add the client certificate to the
1166 * Keychain.
1167 *
1168 * It gives us back a SecIdentityRef that we can use directly. */
1169 #if CURL_BUILD_IOS
1170 const void *cKeys[] = {kSecImportExportPassphrase};
1171 const void *cValues[] = {password};
1172 CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
1173 password ? 1L : 0L, NULL, NULL);
1174
1175 if(options != NULL) {
1176 status = SecPKCS12Import(pkcs_data, options, &items);
1177 CFRelease(options);
1178 }
1179
1180
1181 /* On macOS SecPKCS12Import will always add the client certificate to
1182 * the Keychain.
1183 *
1184 * As this doesn't match iOS, and apps may not want to see their client
1185 * certificate saved in the user's keychain, we use SecItemImport
1186 * with a NULL keychain to avoid importing it.
1187 *
1188 * This returns a SecCertificateRef from which we can construct a
1189 * SecIdentityRef.
1190 */
1191 #elif CURL_BUILD_MAC_10_7
1192 SecItemImportExportKeyParameters keyParams;
1193 SecExternalFormat inputFormat = kSecFormatPKCS12;
1194 SecExternalItemType inputType = kSecItemTypeCertificate;
1195
1196 memset(&keyParams, 0x00, sizeof(keyParams));
1197 keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
1198 keyParams.passphrase = password;
1199
1200 status = SecItemImport(pkcs_data, NULL, &inputFormat, &inputType,
1201 0, &keyParams, NULL, &items);
1202 #endif
1203
1204
1205 /* Extract the SecIdentityRef */
1206 if(status == errSecSuccess && items && CFArrayGetCount(items)) {
1207 CFIndex i, count;
1208 count = CFArrayGetCount(items);
1209
1210 for(i = 0; i < count; i++) {
1211 CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(items, i);
1212 CFTypeID itemID = CFGetTypeID(item);
1213
1214 if(itemID == CFDictionaryGetTypeID()) {
1215 CFTypeRef identity = (CFTypeRef) CFDictionaryGetValue(
1216 (CFDictionaryRef) item,
1217 kSecImportItemIdentity);
1218 CFRetain(identity);
1219 *out_cert_and_key = (SecIdentityRef) identity;
1220 break;
1221 }
1222 #if CURL_BUILD_MAC_10_7
1223 else if(itemID == SecCertificateGetTypeID()) {
1224 status = SecIdentityCreateWithCertificate(NULL,
1225 (SecCertificateRef) item,
1226 out_cert_and_key);
1227 break;
1228 }
1229 #endif
1230 }
1231 }
1232
1233 if(items)
1234 CFRelease(items);
1235 CFRelease(pkcs_data);
1236 }
1237 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1238 if(password)
1239 CFRelease(password);
1240 if(pkcs_url)
1241 CFRelease(pkcs_url);
1242 return status;
1243 }
1244
1245 /* This code was borrowed from nss.c, with some modifications:
1246 * Determine whether the nickname passed in is a filename that needs to
1247 * be loaded as a PEM or a regular NSS nickname.
1248 *
1249 * returns 1 for a file
1250 * returns 0 for not a file
1251 */
is_file(const char * filename)1252 CF_INLINE bool is_file(const char *filename)
1253 {
1254 struct_stat st;
1255
1256 if(filename == NULL)
1257 return false;
1258
1259 if(stat(filename, &st) == 0)
1260 return S_ISREG(st.st_mode);
1261 return false;
1262 }
1263
1264 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
sectransp_version_from_curl(SSLProtocol * darwinver,long ssl_version)1265 static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver,
1266 long ssl_version)
1267 {
1268 switch(ssl_version) {
1269 case CURL_SSLVERSION_TLSv1_0:
1270 *darwinver = kTLSProtocol1;
1271 return CURLE_OK;
1272 case CURL_SSLVERSION_TLSv1_1:
1273 *darwinver = kTLSProtocol11;
1274 return CURLE_OK;
1275 case CURL_SSLVERSION_TLSv1_2:
1276 *darwinver = kTLSProtocol12;
1277 return CURLE_OK;
1278 case CURL_SSLVERSION_TLSv1_3:
1279 /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */
1280 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1281 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1282 *darwinver = kTLSProtocol13;
1283 return CURLE_OK;
1284 }
1285 #endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
1286 HAVE_BUILTIN_AVAILABLE == 1 */
1287 break;
1288 }
1289 return CURLE_SSL_CONNECT_ERROR;
1290 }
1291 #endif
1292
1293 static CURLcode
set_ssl_version_min_max(struct connectdata * conn,int sockindex)1294 set_ssl_version_min_max(struct connectdata *conn, int sockindex)
1295 {
1296 struct Curl_easy *data = conn->data;
1297 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1298 struct ssl_backend_data *backend = connssl->backend;
1299 long ssl_version = SSL_CONN_CONFIG(version);
1300 long ssl_version_max = SSL_CONN_CONFIG(version_max);
1301 long max_supported_version_by_os;
1302
1303 /* macOS 10.5-10.7 supported TLS 1.0 only.
1304 macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
1305 macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
1306 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1307 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1308 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3;
1309 }
1310 else {
1311 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1312 }
1313 #else
1314 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1315 #endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
1316 HAVE_BUILTIN_AVAILABLE == 1 */
1317
1318 switch(ssl_version) {
1319 case CURL_SSLVERSION_DEFAULT:
1320 case CURL_SSLVERSION_TLSv1:
1321 ssl_version = CURL_SSLVERSION_TLSv1_0;
1322 break;
1323 }
1324
1325 switch(ssl_version_max) {
1326 case CURL_SSLVERSION_MAX_NONE:
1327 case CURL_SSLVERSION_MAX_DEFAULT:
1328 ssl_version_max = max_supported_version_by_os;
1329 break;
1330 }
1331
1332 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1333 if(SSLSetProtocolVersionMax != NULL) {
1334 SSLProtocol darwin_ver_min = kTLSProtocol1;
1335 SSLProtocol darwin_ver_max = kTLSProtocol1;
1336 CURLcode result = sectransp_version_from_curl(&darwin_ver_min,
1337 ssl_version);
1338 if(result) {
1339 failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
1340 return result;
1341 }
1342 result = sectransp_version_from_curl(&darwin_ver_max,
1343 ssl_version_max >> 16);
1344 if(result) {
1345 failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
1346 return result;
1347 }
1348
1349 (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min);
1350 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max);
1351 return result;
1352 }
1353 else {
1354 #if CURL_SUPPORT_MAC_10_8
1355 long i = ssl_version;
1356 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1357 kSSLProtocolAll,
1358 false);
1359 for(; i <= (ssl_version_max >> 16); i++) {
1360 switch(i) {
1361 case CURL_SSLVERSION_TLSv1_0:
1362 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1363 kTLSProtocol1,
1364 true);
1365 break;
1366 case CURL_SSLVERSION_TLSv1_1:
1367 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1368 kTLSProtocol11,
1369 true);
1370 break;
1371 case CURL_SSLVERSION_TLSv1_2:
1372 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1373 kTLSProtocol12,
1374 true);
1375 break;
1376 case CURL_SSLVERSION_TLSv1_3:
1377 failf(data, "Your version of the OS does not support TLSv1.3");
1378 return CURLE_SSL_CONNECT_ERROR;
1379 }
1380 }
1381 return CURLE_OK;
1382 #endif /* CURL_SUPPORT_MAC_10_8 */
1383 }
1384 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1385 failf(data, "Secure Transport: cannot set SSL protocol");
1386 return CURLE_SSL_CONNECT_ERROR;
1387 }
1388
1389
sectransp_connect_step1(struct connectdata * conn,int sockindex)1390 static CURLcode sectransp_connect_step1(struct connectdata *conn,
1391 int sockindex)
1392 {
1393 struct Curl_easy *data = conn->data;
1394 curl_socket_t sockfd = conn->sock[sockindex];
1395 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1396 struct ssl_backend_data *backend = connssl->backend;
1397 const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
1398 const struct curl_blob *ssl_cablob = NULL;
1399 const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
1400 char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
1401 const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
1402 #ifndef CURL_DISABLE_PROXY
1403 const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
1404 conn->host.name;
1405 const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
1406 #else
1407 const char * const hostname = conn->host.name;
1408 const long int port = conn->remote_port;
1409 #endif
1410 #ifdef ENABLE_IPV6
1411 struct in6_addr addr;
1412 #else
1413 struct in_addr addr;
1414 #endif /* ENABLE_IPV6 */
1415 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1416 SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1417 OSStatus err = noErr;
1418 #if CURL_BUILD_MAC
1419 int darwinver_maj = 0, darwinver_min = 0;
1420
1421 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1422 #endif /* CURL_BUILD_MAC */
1423
1424 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1425 if(SSLCreateContext != NULL) { /* use the newer API if available */
1426 if(backend->ssl_ctx)
1427 CFRelease(backend->ssl_ctx);
1428 backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1429 if(!backend->ssl_ctx) {
1430 failf(data, "SSL: couldn't create a context!");
1431 return CURLE_OUT_OF_MEMORY;
1432 }
1433 }
1434 else {
1435 /* The old ST API does not exist under iOS, so don't compile it: */
1436 #if CURL_SUPPORT_MAC_10_8
1437 if(backend->ssl_ctx)
1438 (void)SSLDisposeContext(backend->ssl_ctx);
1439 err = SSLNewContext(false, &(backend->ssl_ctx));
1440 if(err != noErr) {
1441 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1442 return CURLE_OUT_OF_MEMORY;
1443 }
1444 #endif /* CURL_SUPPORT_MAC_10_8 */
1445 }
1446 #else
1447 if(backend->ssl_ctx)
1448 (void)SSLDisposeContext(backend->ssl_ctx);
1449 err = SSLNewContext(false, &(backend->ssl_ctx));
1450 if(err != noErr) {
1451 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1452 return CURLE_OUT_OF_MEMORY;
1453 }
1454 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1455 backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1456
1457 /* check to see if we've been told to use an explicit SSL/TLS version */
1458 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1459 if(SSLSetProtocolVersionMax != NULL) {
1460 switch(conn->ssl_config.version) {
1461 case CURL_SSLVERSION_TLSv1:
1462 (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
1463 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1464 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1465 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13);
1466 }
1467 else {
1468 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
1469 }
1470 #else
1471 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
1472 #endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
1473 HAVE_BUILTIN_AVAILABLE == 1 */
1474 break;
1475 case CURL_SSLVERSION_DEFAULT:
1476 case CURL_SSLVERSION_TLSv1_0:
1477 case CURL_SSLVERSION_TLSv1_1:
1478 case CURL_SSLVERSION_TLSv1_2:
1479 case CURL_SSLVERSION_TLSv1_3:
1480 {
1481 CURLcode result = set_ssl_version_min_max(conn, sockindex);
1482 if(result != CURLE_OK)
1483 return result;
1484 break;
1485 }
1486 case CURL_SSLVERSION_SSLv3:
1487 err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol3);
1488 if(err != noErr) {
1489 failf(data, "Your version of the OS does not support SSLv3");
1490 return CURLE_SSL_CONNECT_ERROR;
1491 }
1492 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol3);
1493 break;
1494 case CURL_SSLVERSION_SSLv2:
1495 err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol2);
1496 if(err != noErr) {
1497 failf(data, "Your version of the OS does not support SSLv2");
1498 return CURLE_SSL_CONNECT_ERROR;
1499 }
1500 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol2);
1501 break;
1502 default:
1503 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1504 return CURLE_SSL_CONNECT_ERROR;
1505 }
1506 }
1507 else {
1508 #if CURL_SUPPORT_MAC_10_8
1509 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1510 kSSLProtocolAll,
1511 false);
1512 switch(conn->ssl_config.version) {
1513 case CURL_SSLVERSION_DEFAULT:
1514 case CURL_SSLVERSION_TLSv1:
1515 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1516 kTLSProtocol1,
1517 true);
1518 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1519 kTLSProtocol11,
1520 true);
1521 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1522 kTLSProtocol12,
1523 true);
1524 break;
1525 case CURL_SSLVERSION_TLSv1_0:
1526 case CURL_SSLVERSION_TLSv1_1:
1527 case CURL_SSLVERSION_TLSv1_2:
1528 case CURL_SSLVERSION_TLSv1_3:
1529 {
1530 CURLcode result = set_ssl_version_min_max(conn, sockindex);
1531 if(result != CURLE_OK)
1532 return result;
1533 break;
1534 }
1535 case CURL_SSLVERSION_SSLv3:
1536 err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1537 kSSLProtocol3,
1538 true);
1539 if(err != noErr) {
1540 failf(data, "Your version of the OS does not support SSLv3");
1541 return CURLE_SSL_CONNECT_ERROR;
1542 }
1543 break;
1544 case CURL_SSLVERSION_SSLv2:
1545 err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1546 kSSLProtocol2,
1547 true);
1548 if(err != noErr) {
1549 failf(data, "Your version of the OS does not support SSLv2");
1550 return CURLE_SSL_CONNECT_ERROR;
1551 }
1552 break;
1553 default:
1554 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1555 return CURLE_SSL_CONNECT_ERROR;
1556 }
1557 #endif /* CURL_SUPPORT_MAC_10_8 */
1558 }
1559 #else
1560 if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
1561 failf(data, "Your version of the OS does not support to set maximum"
1562 " SSL/TLS version");
1563 return CURLE_SSL_CONNECT_ERROR;
1564 }
1565 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false);
1566 switch(conn->ssl_config.version) {
1567 case CURL_SSLVERSION_DEFAULT:
1568 case CURL_SSLVERSION_TLSv1:
1569 case CURL_SSLVERSION_TLSv1_0:
1570 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1571 kTLSProtocol1,
1572 true);
1573 break;
1574 case CURL_SSLVERSION_TLSv1_1:
1575 failf(data, "Your version of the OS does not support TLSv1.1");
1576 return CURLE_SSL_CONNECT_ERROR;
1577 case CURL_SSLVERSION_TLSv1_2:
1578 failf(data, "Your version of the OS does not support TLSv1.2");
1579 return CURLE_SSL_CONNECT_ERROR;
1580 case CURL_SSLVERSION_TLSv1_3:
1581 failf(data, "Your version of the OS does not support TLSv1.3");
1582 return CURLE_SSL_CONNECT_ERROR;
1583 case CURL_SSLVERSION_SSLv2:
1584 err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1585 kSSLProtocol2,
1586 true);
1587 if(err != noErr) {
1588 failf(data, "Your version of the OS does not support SSLv2");
1589 return CURLE_SSL_CONNECT_ERROR;
1590 }
1591 break;
1592 case CURL_SSLVERSION_SSLv3:
1593 err = SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1594 kSSLProtocol3,
1595 true);
1596 if(err != noErr) {
1597 failf(data, "Your version of the OS does not support SSLv3");
1598 return CURLE_SSL_CONNECT_ERROR;
1599 }
1600 break;
1601 default:
1602 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1603 return CURLE_SSL_CONNECT_ERROR;
1604 }
1605 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1606
1607 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1608 if(conn->bits.tls_enable_alpn) {
1609 if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
1610 CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0,
1611 &kCFTypeArrayCallBacks);
1612
1613 #ifdef USE_NGHTTP2
1614 if(data->set.httpversion >= CURL_HTTP_VERSION_2
1615 #ifndef CURL_DISABLE_PROXY
1616 && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
1617 #endif
1618 ) {
1619 CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID));
1620 infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
1621 }
1622 #endif
1623
1624 CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1));
1625 infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
1626
1627 /* expects length prefixed preference ordered list of protocols in wire
1628 * format
1629 */
1630 err = SSLSetALPNProtocols(backend->ssl_ctx, alpnArr);
1631 if(err != noErr)
1632 infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n",
1633 err);
1634 CFRelease(alpnArr);
1635 }
1636 }
1637 #endif
1638
1639 if(SSL_SET_OPTION(key)) {
1640 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1641 "Transport. The private key must be in the Keychain.\n");
1642 }
1643
1644 if(ssl_cert || ssl_cert_blob) {
1645 bool is_cert_data = ssl_cert_blob != NULL;
1646 bool is_cert_file = (!is_cert_data) && is_file(ssl_cert);
1647 SecIdentityRef cert_and_key = NULL;
1648
1649 /* User wants to authenticate with a client cert. Look for it:
1650 If we detect that this is a file on disk, then let's load it.
1651 Otherwise, assume that the user wants to use an identity loaded
1652 from the Keychain. */
1653 if(is_cert_file || is_cert_data) {
1654 if(!SSL_SET_OPTION(cert_type))
1655 infof(data, "WARNING: SSL: Certificate type not set, assuming "
1656 "PKCS#12 format.\n");
1657 else if(strncmp(SSL_SET_OPTION(cert_type), "P12",
1658 strlen(SSL_SET_OPTION(cert_type))) != 0)
1659 infof(data, "WARNING: SSL: The Security framework only supports "
1660 "loading identities that are in PKCS#12 format.\n");
1661
1662 err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob,
1663 SSL_SET_OPTION(key_passwd), &cert_and_key);
1664 }
1665 else
1666 err = CopyIdentityWithLabel(ssl_cert, &cert_and_key);
1667
1668 if(err == noErr && cert_and_key) {
1669 SecCertificateRef cert = NULL;
1670 CFTypeRef certs_c[1];
1671 CFArrayRef certs;
1672
1673 /* If we found one, print it out: */
1674 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1675 if(err == noErr) {
1676 char *certp;
1677 CURLcode result = CopyCertSubject(data, cert, &certp);
1678 if(!result) {
1679 infof(data, "Client certificate: %s\n", certp);
1680 free(certp);
1681 }
1682
1683 CFRelease(cert);
1684 if(result == CURLE_PEER_FAILED_VERIFICATION)
1685 return CURLE_SSL_CERTPROBLEM;
1686 if(result)
1687 return result;
1688 }
1689 certs_c[0] = cert_and_key;
1690 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1691 &kCFTypeArrayCallBacks);
1692 err = SSLSetCertificate(backend->ssl_ctx, certs);
1693 if(certs)
1694 CFRelease(certs);
1695 if(err != noErr) {
1696 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1697 return CURLE_SSL_CERTPROBLEM;
1698 }
1699 CFRelease(cert_and_key);
1700 }
1701 else {
1702 const char *cert_showfilename_error =
1703 is_cert_data ? "(memory blob)" : ssl_cert;
1704
1705 switch(err) {
1706 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1707 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1708 "and its private key.", cert_showfilename_error);
1709 break;
1710 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1711 failf(data, "SSL: Couldn't make sense of the data in the "
1712 "certificate \"%s\" and its private key.",
1713 cert_showfilename_error);
1714 break;
1715 case -25260: /* errSecPassphraseRequired */
1716 failf(data, "SSL The certificate \"%s\" requires a password.",
1717 cert_showfilename_error);
1718 break;
1719 case errSecItemNotFound:
1720 failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1721 "key in the Keychain.", cert_showfilename_error);
1722 break;
1723 default:
1724 failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1725 "key: OSStatus %d", cert_showfilename_error, err);
1726 break;
1727 }
1728 return CURLE_SSL_CERTPROBLEM;
1729 }
1730 }
1731
1732 /* SSL always tries to verify the peer, this only says whether it should
1733 * fail to connect if the verification fails, or if it should continue
1734 * anyway. In the latter case the result of the verification is checked with
1735 * SSL_get_verify_result() below. */
1736 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1737 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1738 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1739 works, it doesn't work as expected under Snow Leopard, Lion or
1740 Mountain Lion.
1741 So we need to call SSLSetEnableCertVerify() on those older cats in order
1742 to disable certificate validation if the user turned that off.
1743 (SecureTransport will always validate the certificate chain by
1744 default.)
1745 Note:
1746 Darwin 11.x.x is Lion (10.7)
1747 Darwin 12.x.x is Mountain Lion (10.8)
1748 Darwin 13.x.x is Mavericks (10.9)
1749 Darwin 14.x.x is Yosemite (10.10)
1750 Darwin 15.x.x is El Capitan (10.11)
1751 */
1752 #if CURL_BUILD_MAC
1753 if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
1754 #else
1755 if(SSLSetSessionOption != NULL) {
1756 #endif /* CURL_BUILD_MAC */
1757 bool break_on_auth = !conn->ssl_config.verifypeer ||
1758 ssl_cafile || ssl_cablob;
1759 err = SSLSetSessionOption(backend->ssl_ctx,
1760 kSSLSessionOptionBreakOnServerAuth,
1761 break_on_auth);
1762 if(err != noErr) {
1763 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1764 return CURLE_SSL_CONNECT_ERROR;
1765 }
1766 }
1767 else {
1768 #if CURL_SUPPORT_MAC_10_8
1769 err = SSLSetEnableCertVerify(backend->ssl_ctx,
1770 conn->ssl_config.verifypeer?true:false);
1771 if(err != noErr) {
1772 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1773 return CURLE_SSL_CONNECT_ERROR;
1774 }
1775 #endif /* CURL_SUPPORT_MAC_10_8 */
1776 }
1777 #else
1778 err = SSLSetEnableCertVerify(backend->ssl_ctx,
1779 conn->ssl_config.verifypeer?true:false);
1780 if(err != noErr) {
1781 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1782 return CURLE_SSL_CONNECT_ERROR;
1783 }
1784 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1785
1786 if((ssl_cafile || ssl_cablob) && verifypeer) {
1787 bool is_cert_data = ssl_cablob != NULL;
1788 bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile);
1789
1790 if(!(is_cert_file || is_cert_data)) {
1791 failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
1792 return CURLE_SSL_CACERT_BADFILE;
1793 }
1794 }
1795
1796 /* Configure hostname check. SNI is used if available.
1797 * Both hostname check and SNI require SSLSetPeerDomainName().
1798 * Also: the verifyhost setting influences SNI usage */
1799 if(conn->ssl_config.verifyhost) {
1800 err = SSLSetPeerDomainName(backend->ssl_ctx, hostname,
1801 strlen(hostname));
1802
1803 if(err != noErr) {
1804 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1805 err);
1806 }
1807
1808 if((Curl_inet_pton(AF_INET, hostname, &addr))
1809 #ifdef ENABLE_IPV6
1810 || (Curl_inet_pton(AF_INET6, hostname, &addr))
1811 #endif
1812 ) {
1813 infof(data, "WARNING: using IP address, SNI is being disabled by "
1814 "the OS.\n");
1815 }
1816 }
1817 else {
1818 infof(data, "WARNING: disabling hostname validation also disables SNI.\n");
1819 }
1820
1821 /* Disable cipher suites that ST supports but are not safe. These ciphers
1822 are unlikely to be used in any case since ST gives other ciphers a much
1823 higher priority, but it's probably better that we not connect at all than
1824 to give the user a false sense of security if the server only supports
1825 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1826 err = SSLGetNumberSupportedCiphers(backend->ssl_ctx, &all_ciphers_count);
1827 if(err != noErr) {
1828 failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d",
1829 err);
1830 return CURLE_SSL_CIPHER;
1831 }
1832 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1833 if(!all_ciphers) {
1834 failf(data, "SSL: Failed to allocate memory for all ciphers");
1835 return CURLE_OUT_OF_MEMORY;
1836 }
1837 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1838 if(!allowed_ciphers) {
1839 Curl_safefree(all_ciphers);
1840 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1841 return CURLE_OUT_OF_MEMORY;
1842 }
1843 err = SSLGetSupportedCiphers(backend->ssl_ctx, all_ciphers,
1844 &all_ciphers_count);
1845 if(err != noErr) {
1846 Curl_safefree(all_ciphers);
1847 Curl_safefree(allowed_ciphers);
1848 return CURLE_SSL_CIPHER;
1849 }
1850 for(i = 0UL ; i < all_ciphers_count ; i++) {
1851 #if CURL_BUILD_MAC
1852 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1853 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1854 Work around the problem here by disabling those ciphers if we are
1855 running in an affected version of OS X. */
1856 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1857 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1858 continue;
1859 }
1860 #endif /* CURL_BUILD_MAC */
1861 switch(all_ciphers[i]) {
1862 /* Disable NULL ciphersuites: */
1863 case SSL_NULL_WITH_NULL_NULL:
1864 case SSL_RSA_WITH_NULL_MD5:
1865 case SSL_RSA_WITH_NULL_SHA:
1866 case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1867 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1868 case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1869 case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1870 case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1871 case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1872 case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1873 case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1874 case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1875 case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1876 case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1877 case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1878 case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1879 case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1880 case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1881 /* Disable anonymous ciphersuites: */
1882 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1883 case SSL_DH_anon_WITH_RC4_128_MD5:
1884 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1885 case SSL_DH_anon_WITH_DES_CBC_SHA:
1886 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1887 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1888 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1889 case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1890 case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1891 case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1892 case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1893 case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1894 case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1895 case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1896 case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1897 case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1898 /* Disable weak key ciphersuites: */
1899 case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1900 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1901 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1902 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1903 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1904 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1905 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1906 case SSL_RSA_WITH_DES_CBC_SHA:
1907 case SSL_DH_DSS_WITH_DES_CBC_SHA:
1908 case SSL_DH_RSA_WITH_DES_CBC_SHA:
1909 case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1910 case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1911 /* Disable IDEA: */
1912 case SSL_RSA_WITH_IDEA_CBC_SHA:
1913 case SSL_RSA_WITH_IDEA_CBC_MD5:
1914 /* Disable RC4: */
1915 case SSL_RSA_WITH_RC4_128_MD5:
1916 case SSL_RSA_WITH_RC4_128_SHA:
1917 case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
1918 case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/
1919 case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
1920 case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
1921 case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */
1922 case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */
1923 case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */
1924 break;
1925 default: /* enable everything else */
1926 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1927 break;
1928 }
1929 }
1930 err = SSLSetEnabledCiphers(backend->ssl_ctx, allowed_ciphers,
1931 allowed_ciphers_count);
1932 Curl_safefree(all_ciphers);
1933 Curl_safefree(allowed_ciphers);
1934 if(err != noErr) {
1935 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1936 return CURLE_SSL_CIPHER;
1937 }
1938
1939 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1940 /* We want to enable 1/n-1 when using a CBC cipher unless the user
1941 specifically doesn't want us doing that: */
1942 if(SSLSetSessionOption != NULL) {
1943 SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1944 !data->set.ssl.enable_beast);
1945 SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
1946 data->set.ssl.falsestart); /* false start support */
1947 }
1948 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1949
1950 /* Check if there's a cached ID we can/should use here! */
1951 if(SSL_SET_OPTION(primary.sessionid)) {
1952 char *ssl_sessionid;
1953 size_t ssl_sessionid_len;
1954
1955 Curl_ssl_sessionid_lock(conn);
1956 if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1957 &ssl_sessionid_len, sockindex)) {
1958 /* we got a session id, use it! */
1959 err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1960 Curl_ssl_sessionid_unlock(conn);
1961 if(err != noErr) {
1962 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1963 return CURLE_SSL_CONNECT_ERROR;
1964 }
1965 /* Informational message */
1966 infof(data, "SSL re-using session ID\n");
1967 }
1968 /* If there isn't one, then let's make one up! This has to be done prior
1969 to starting the handshake. */
1970 else {
1971 CURLcode result;
1972 ssl_sessionid =
1973 aprintf("%s:%d:%d:%s:%hu", ssl_cafile,
1974 verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
1975 ssl_sessionid_len = strlen(ssl_sessionid);
1976
1977 err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1978 if(err != noErr) {
1979 Curl_ssl_sessionid_unlock(conn);
1980 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1981 return CURLE_SSL_CONNECT_ERROR;
1982 }
1983
1984 result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len,
1985 sockindex);
1986 Curl_ssl_sessionid_unlock(conn);
1987 if(result) {
1988 failf(data, "failed to store ssl session");
1989 return result;
1990 }
1991 }
1992 }
1993
1994 err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite);
1995 if(err != noErr) {
1996 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1997 return CURLE_SSL_CONNECT_ERROR;
1998 }
1999
2000 /* pass the raw socket into the SSL layers */
2001 /* We need to store the FD in a constant memory address, because
2002 * SSLSetConnection() will not copy that address. I've found that
2003 * conn->sock[sockindex] may change on its own. */
2004 backend->ssl_sockfd = sockfd;
2005 err = SSLSetConnection(backend->ssl_ctx, connssl);
2006 if(err != noErr) {
2007 failf(data, "SSL: SSLSetConnection() failed: %d", err);
2008 return CURLE_SSL_CONNECT_ERROR;
2009 }
2010
2011 connssl->connecting_state = ssl_connect_2;
2012 return CURLE_OK;
2013 }
2014
2015 static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
2016 {
2017 char *sep_start, *sep_end, *cert_start, *cert_end;
2018 size_t i, j, err;
2019 size_t len;
2020 unsigned char *b64;
2021
2022 /* Jump through the separators at the beginning of the certificate. */
2023 sep_start = strstr(in, "-----");
2024 if(sep_start == NULL)
2025 return 0;
2026 cert_start = strstr(sep_start + 1, "-----");
2027 if(cert_start == NULL)
2028 return -1;
2029
2030 cert_start += 5;
2031
2032 /* Find separator after the end of the certificate. */
2033 cert_end = strstr(cert_start, "-----");
2034 if(cert_end == NULL)
2035 return -1;
2036
2037 sep_end = strstr(cert_end + 1, "-----");
2038 if(sep_end == NULL)
2039 return -1;
2040 sep_end += 5;
2041
2042 len = cert_end - cert_start;
2043 b64 = malloc(len + 1);
2044 if(!b64)
2045 return -1;
2046
2047 /* Create base64 string without linefeeds. */
2048 for(i = 0, j = 0; i < len; i++) {
2049 if(cert_start[i] != '\r' && cert_start[i] != '\n')
2050 b64[j++] = cert_start[i];
2051 }
2052 b64[j] = '\0';
2053
2054 err = Curl_base64_decode((const char *)b64, out, outlen);
2055 free(b64);
2056 if(err) {
2057 free(*out);
2058 return -1;
2059 }
2060
2061 return sep_end - in;
2062 }
2063
2064 static int read_cert(const char *file, unsigned char **out, size_t *outlen)
2065 {
2066 int fd;
2067 ssize_t n, len = 0, cap = 512;
2068 unsigned char buf[512], *data;
2069
2070 fd = open(file, 0);
2071 if(fd < 0)
2072 return -1;
2073
2074 data = malloc(cap);
2075 if(!data) {
2076 close(fd);
2077 return -1;
2078 }
2079
2080 for(;;) {
2081 n = read(fd, buf, sizeof(buf));
2082 if(n < 0) {
2083 close(fd);
2084 free(data);
2085 return -1;
2086 }
2087 else if(n == 0) {
2088 close(fd);
2089 break;
2090 }
2091
2092 if(len + n >= cap) {
2093 cap *= 2;
2094 data = Curl_saferealloc(data, cap);
2095 if(!data) {
2096 close(fd);
2097 return -1;
2098 }
2099 }
2100
2101 memcpy(data + len, buf, n);
2102 len += n;
2103 }
2104 data[len] = '\0';
2105
2106 *out = data;
2107 *outlen = len;
2108
2109 return 0;
2110 }
2111
2112 static int append_cert_to_array(struct Curl_easy *data,
2113 unsigned char *buf, size_t buflen,
2114 CFMutableArrayRef array)
2115 {
2116 CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
2117 char *certp;
2118 CURLcode result;
2119 if(!certdata) {
2120 failf(data, "SSL: failed to allocate array for CA certificate");
2121 return CURLE_OUT_OF_MEMORY;
2122 }
2123
2124 SecCertificateRef cacert =
2125 SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
2126 CFRelease(certdata);
2127 if(!cacert) {
2128 failf(data, "SSL: failed to create SecCertificate from CA certificate");
2129 return CURLE_SSL_CACERT_BADFILE;
2130 }
2131
2132 /* Check if cacert is valid. */
2133 result = CopyCertSubject(data, cacert, &certp);
2134 switch(result) {
2135 case CURLE_OK:
2136 break;
2137 case CURLE_PEER_FAILED_VERIFICATION:
2138 return CURLE_SSL_CACERT_BADFILE;
2139 case CURLE_OUT_OF_MEMORY:
2140 default:
2141 return result;
2142 }
2143 free(certp);
2144
2145 CFArrayAppendValue(array, cacert);
2146 CFRelease(cacert);
2147
2148 return CURLE_OK;
2149 }
2150
2151 static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
2152 SSLContextRef ctx)
2153 {
2154 int n = 0, rc;
2155 long res;
2156 unsigned char *certbuf, *der;
2157 size_t buflen, derlen, offset = 0;
2158
2159 if(read_cert(cafile, &certbuf, &buflen) < 0) {
2160 failf(data, "SSL: failed to read or invalid CA certificate");
2161 return CURLE_SSL_CACERT_BADFILE;
2162 }
2163
2164 /*
2165 * Certbuf now contains the contents of the certificate file, which can be
2166 * - a single DER certificate,
2167 * - a single PEM certificate or
2168 * - a bunch of PEM certificates (certificate bundle).
2169 *
2170 * Go through certbuf, and convert any PEM certificate in it into DER
2171 * format.
2172 */
2173 CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
2174 &kCFTypeArrayCallBacks);
2175 if(array == NULL) {
2176 free(certbuf);
2177 failf(data, "SSL: out of memory creating CA certificate array");
2178 return CURLE_OUT_OF_MEMORY;
2179 }
2180
2181 while(offset < buflen) {
2182 n++;
2183
2184 /*
2185 * Check if the certificate is in PEM format, and convert it to DER. If
2186 * this fails, we assume the certificate is in DER format.
2187 */
2188 res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
2189 if(res < 0) {
2190 free(certbuf);
2191 CFRelease(array);
2192 failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
2193 n, offset);
2194 return CURLE_SSL_CACERT_BADFILE;
2195 }
2196 offset += res;
2197
2198 if(res == 0 && offset == 0) {
2199 /* This is not a PEM file, probably a certificate in DER format. */
2200 rc = append_cert_to_array(data, certbuf, buflen, array);
2201 free(certbuf);
2202 if(rc != CURLE_OK) {
2203 CFRelease(array);
2204 return rc;
2205 }
2206 break;
2207 }
2208 else if(res == 0) {
2209 /* No more certificates in the bundle. */
2210 free(certbuf);
2211 break;
2212 }
2213
2214 rc = append_cert_to_array(data, der, derlen, array);
2215 free(der);
2216 if(rc != CURLE_OK) {
2217 free(certbuf);
2218 CFRelease(array);
2219 return rc;
2220 }
2221 }
2222
2223 SecTrustRef trust;
2224 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2225 if(trust == NULL) {
2226 failf(data, "SSL: error getting certificate chain");
2227 CFRelease(array);
2228 return CURLE_PEER_FAILED_VERIFICATION;
2229 }
2230 else if(ret != noErr) {
2231 CFRelease(array);
2232 failf(data, "SSLCopyPeerTrust() returned error %d", ret);
2233 return CURLE_PEER_FAILED_VERIFICATION;
2234 }
2235
2236 ret = SecTrustSetAnchorCertificates(trust, array);
2237 if(ret != noErr) {
2238 CFRelease(array);
2239 CFRelease(trust);
2240 failf(data, "SecTrustSetAnchorCertificates() returned error %d", ret);
2241 return CURLE_PEER_FAILED_VERIFICATION;
2242 }
2243 ret = SecTrustSetAnchorCertificatesOnly(trust, true);
2244 if(ret != noErr) {
2245 CFRelease(array);
2246 CFRelease(trust);
2247 failf(data, "SecTrustSetAnchorCertificatesOnly() returned error %d", ret);
2248 return CURLE_PEER_FAILED_VERIFICATION;
2249 }
2250
2251 SecTrustResultType trust_eval = 0;
2252 ret = SecTrustEvaluate(trust, &trust_eval);
2253 CFRelease(array);
2254 CFRelease(trust);
2255 if(ret != noErr) {
2256 failf(data, "SecTrustEvaluate() returned error %d", ret);
2257 return CURLE_PEER_FAILED_VERIFICATION;
2258 }
2259
2260 switch(trust_eval) {
2261 case kSecTrustResultUnspecified:
2262 case kSecTrustResultProceed:
2263 return CURLE_OK;
2264
2265 case kSecTrustResultRecoverableTrustFailure:
2266 case kSecTrustResultDeny:
2267 default:
2268 failf(data, "SSL: certificate verification failed (result: %d)",
2269 trust_eval);
2270 return CURLE_PEER_FAILED_VERIFICATION;
2271 }
2272 }
2273
2274 #ifdef SECTRANSP_PINNEDPUBKEY
2275 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
2276 SSLContextRef ctx,
2277 const char *pinnedpubkey)
2278 { /* Scratch */
2279 size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24;
2280 unsigned char *pubkey = NULL, *realpubkey = NULL;
2281 const unsigned char *spkiHeader = NULL;
2282 CFDataRef publicKeyBits = NULL;
2283
2284 /* Result is returned to caller */
2285 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
2286
2287 /* if a path wasn't specified, don't pin */
2288 if(!pinnedpubkey)
2289 return CURLE_OK;
2290
2291
2292 if(!ctx)
2293 return result;
2294
2295 do {
2296 SecTrustRef trust;
2297 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2298 if(ret != noErr || trust == NULL)
2299 break;
2300
2301 SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
2302 CFRelease(trust);
2303 if(keyRef == NULL)
2304 break;
2305
2306 #ifdef SECTRANSP_PINNEDPUBKEY_V1
2307
2308 publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL);
2309 CFRelease(keyRef);
2310 if(publicKeyBits == NULL)
2311 break;
2312
2313 #elif SECTRANSP_PINNEDPUBKEY_V2
2314
2315 OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL,
2316 &publicKeyBits);
2317 CFRelease(keyRef);
2318 if(success != errSecSuccess || publicKeyBits == NULL)
2319 break;
2320
2321 #endif /* SECTRANSP_PINNEDPUBKEY_V2 */
2322
2323 pubkeylen = CFDataGetLength(publicKeyBits);
2324 pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits);
2325
2326 switch(pubkeylen) {
2327 case 526:
2328 /* 4096 bit RSA pubkeylen == 526 */
2329 spkiHeader = rsa4096SpkiHeader;
2330 break;
2331 case 270:
2332 /* 2048 bit RSA pubkeylen == 270 */
2333 spkiHeader = rsa2048SpkiHeader;
2334 break;
2335 #ifdef SECTRANSP_PINNEDPUBKEY_V1
2336 case 65:
2337 /* ecDSA secp256r1 pubkeylen == 65 */
2338 spkiHeader = ecDsaSecp256r1SpkiHeader;
2339 spkiHeaderLength = 26;
2340 break;
2341 case 97:
2342 /* ecDSA secp384r1 pubkeylen == 97 */
2343 spkiHeader = ecDsaSecp384r1SpkiHeader;
2344 spkiHeaderLength = 23;
2345 break;
2346 default:
2347 infof(data, "SSL: unhandled public key length: %d\n", pubkeylen);
2348 #elif SECTRANSP_PINNEDPUBKEY_V2
2349 default:
2350 /* ecDSA secp256r1 pubkeylen == 91 header already included?
2351 * ecDSA secp384r1 header already included too
2352 * we assume rest of algorithms do same, so do nothing
2353 */
2354 result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey,
2355 pubkeylen);
2356 #endif /* SECTRANSP_PINNEDPUBKEY_V2 */
2357 continue; /* break from loop */
2358 }
2359
2360 realpubkeylen = pubkeylen + spkiHeaderLength;
2361 realpubkey = malloc(realpubkeylen);
2362 if(!realpubkey)
2363 break;
2364
2365 memcpy(realpubkey, spkiHeader, spkiHeaderLength);
2366 memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen);
2367
2368 result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey,
2369 realpubkeylen);
2370
2371 } while(0);
2372
2373 Curl_safefree(realpubkey);
2374 if(publicKeyBits != NULL)
2375 CFRelease(publicKeyBits);
2376
2377 return result;
2378 }
2379 #endif /* SECTRANSP_PINNEDPUBKEY */
2380
2381 static CURLcode
2382 sectransp_connect_step2(struct connectdata *conn, int sockindex)
2383 {
2384 struct Curl_easy *data = conn->data;
2385 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2386 struct ssl_backend_data *backend = connssl->backend;
2387 OSStatus err;
2388 SSLCipherSuite cipher;
2389 SSLProtocol protocol = 0;
2390 #ifndef CURL_DISABLE_PROXY
2391 const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
2392 conn->host.name;
2393 #else
2394 const char * const hostname = conn->host.name;
2395 #endif
2396
2397 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
2398 || ssl_connect_2_reading == connssl->connecting_state
2399 || ssl_connect_2_writing == connssl->connecting_state);
2400
2401 /* Here goes nothing: */
2402 err = SSLHandshake(backend->ssl_ctx);
2403
2404 if(err != noErr) {
2405 switch(err) {
2406 case errSSLWouldBlock: /* they're not done with us yet */
2407 connssl->connecting_state = backend->ssl_direction ?
2408 ssl_connect_2_writing : ssl_connect_2_reading;
2409 return CURLE_OK;
2410
2411 /* The below is errSSLServerAuthCompleted; it's not defined in
2412 Leopard's headers */
2413 case -9841:
2414 if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
2415 CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data,
2416 backend->ssl_ctx);
2417 if(result)
2418 return result;
2419 }
2420 /* the documentation says we need to call SSLHandshake() again */
2421 return sectransp_connect_step2(conn, sockindex);
2422
2423 /* Problem with encrypt / decrypt */
2424 case errSSLPeerDecodeError:
2425 failf(data, "Decode failed");
2426 break;
2427 case errSSLDecryptionFail:
2428 case errSSLPeerDecryptionFail:
2429 failf(data, "Decryption failed");
2430 break;
2431 case errSSLPeerDecryptError:
2432 failf(data, "A decryption error occurred");
2433 break;
2434 case errSSLBadCipherSuite:
2435 failf(data, "A bad SSL cipher suite was encountered");
2436 break;
2437 case errSSLCrypto:
2438 failf(data, "An underlying cryptographic error was encountered");
2439 break;
2440 #if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9
2441 case errSSLWeakPeerEphemeralDHKey:
2442 failf(data, "Indicates a weak ephemeral Diffie-Hellman key");
2443 break;
2444 #endif
2445
2446 /* Problem with the message record validation */
2447 case errSSLBadRecordMac:
2448 case errSSLPeerBadRecordMac:
2449 failf(data, "A record with a bad message authentication code (MAC) "
2450 "was encountered");
2451 break;
2452 case errSSLRecordOverflow:
2453 case errSSLPeerRecordOverflow:
2454 failf(data, "A record overflow occurred");
2455 break;
2456
2457 /* Problem with zlib decompression */
2458 case errSSLPeerDecompressFail:
2459 failf(data, "Decompression failed");
2460 break;
2461
2462 /* Problem with access */
2463 case errSSLPeerAccessDenied:
2464 failf(data, "Access was denied");
2465 break;
2466 case errSSLPeerInsufficientSecurity:
2467 failf(data, "There is insufficient security for this operation");
2468 break;
2469
2470 /* These are all certificate problems with the server: */
2471 case errSSLXCertChainInvalid:
2472 failf(data, "SSL certificate problem: Invalid certificate chain");
2473 return CURLE_PEER_FAILED_VERIFICATION;
2474 case errSSLUnknownRootCert:
2475 failf(data, "SSL certificate problem: Untrusted root certificate");
2476 return CURLE_PEER_FAILED_VERIFICATION;
2477 case errSSLNoRootCert:
2478 failf(data, "SSL certificate problem: No root certificate");
2479 return CURLE_PEER_FAILED_VERIFICATION;
2480 case errSSLCertNotYetValid:
2481 failf(data, "SSL certificate problem: The certificate chain had a "
2482 "certificate that is not yet valid");
2483 return CURLE_PEER_FAILED_VERIFICATION;
2484 case errSSLCertExpired:
2485 case errSSLPeerCertExpired:
2486 failf(data, "SSL certificate problem: Certificate chain had an "
2487 "expired certificate");
2488 return CURLE_PEER_FAILED_VERIFICATION;
2489 case errSSLBadCert:
2490 case errSSLPeerBadCert:
2491 failf(data, "SSL certificate problem: Couldn't understand the server "
2492 "certificate format");
2493 return CURLE_PEER_FAILED_VERIFICATION;
2494 case errSSLPeerUnsupportedCert:
2495 failf(data, "SSL certificate problem: An unsupported certificate "
2496 "format was encountered");
2497 return CURLE_PEER_FAILED_VERIFICATION;
2498 case errSSLPeerCertRevoked:
2499 failf(data, "SSL certificate problem: The certificate was revoked");
2500 return CURLE_PEER_FAILED_VERIFICATION;
2501 case errSSLPeerCertUnknown:
2502 failf(data, "SSL certificate problem: The certificate is unknown");
2503 return CURLE_PEER_FAILED_VERIFICATION;
2504
2505 /* These are all certificate problems with the client: */
2506 case errSecAuthFailed:
2507 failf(data, "SSL authentication failed");
2508 break;
2509 case errSSLPeerHandshakeFail:
2510 failf(data, "SSL peer handshake failed, the server most likely "
2511 "requires a client certificate to connect");
2512 break;
2513 case errSSLPeerUnknownCA:
2514 failf(data, "SSL server rejected the client certificate due to "
2515 "the certificate being signed by an unknown certificate "
2516 "authority");
2517 break;
2518
2519 /* This error is raised if the server's cert didn't match the server's
2520 host name: */
2521 case errSSLHostNameMismatch:
2522 failf(data, "SSL certificate peer verification failed, the "
2523 "certificate did not match \"%s\"\n", conn->host.dispname);
2524 return CURLE_PEER_FAILED_VERIFICATION;
2525
2526 /* Problem with SSL / TLS negotiation */
2527 case errSSLNegotiation:
2528 failf(data, "Could not negotiate an SSL cipher suite with the server");
2529 break;
2530 case errSSLBadConfiguration:
2531 failf(data, "A configuration error occurred");
2532 break;
2533 case errSSLProtocol:
2534 failf(data, "SSL protocol error");
2535 break;
2536 case errSSLPeerProtocolVersion:
2537 failf(data, "A bad protocol version was encountered");
2538 break;
2539 case errSSLPeerNoRenegotiation:
2540 failf(data, "No renegotiation is allowed");
2541 break;
2542
2543 /* Generic handshake errors: */
2544 case errSSLConnectionRefused:
2545 failf(data, "Server dropped the connection during the SSL handshake");
2546 break;
2547 case errSSLClosedAbort:
2548 failf(data, "Server aborted the SSL handshake");
2549 break;
2550 case errSSLClosedGraceful:
2551 failf(data, "The connection closed gracefully");
2552 break;
2553 case errSSLClosedNoNotify:
2554 failf(data, "The server closed the session with no notification");
2555 break;
2556 /* Sometimes paramErr happens with buggy ciphers: */
2557 case paramErr:
2558 case errSSLInternal:
2559 case errSSLPeerInternalError:
2560 failf(data, "Internal SSL engine error encountered during the "
2561 "SSL handshake");
2562 break;
2563 case errSSLFatalAlert:
2564 failf(data, "Fatal SSL engine error encountered during the SSL "
2565 "handshake");
2566 break;
2567 /* Unclassified error */
2568 case errSSLBufferOverflow:
2569 failf(data, "An insufficient buffer was provided");
2570 break;
2571 case errSSLIllegalParam:
2572 failf(data, "An illegal parameter was encountered");
2573 break;
2574 case errSSLModuleAttach:
2575 failf(data, "Module attach failure");
2576 break;
2577 case errSSLSessionNotFound:
2578 failf(data, "An attempt to restore an unknown session failed");
2579 break;
2580 case errSSLPeerExportRestriction:
2581 failf(data, "An export restriction occurred");
2582 break;
2583 case errSSLPeerUserCancelled:
2584 failf(data, "The user canceled the operation");
2585 break;
2586 case errSSLPeerUnexpectedMsg:
2587 failf(data, "Peer rejected unexpected message");
2588 break;
2589 #if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9
2590 /* Treaing non-fatal error as fatal like before */
2591 case errSSLClientHelloReceived:
2592 failf(data, "A non-fatal result for providing a server name "
2593 "indication");
2594 break;
2595 #endif
2596
2597 /* Error codes defined in the enum but should never be returned.
2598 We list them here just in case. */
2599 #if CURL_BUILD_MAC_10_6
2600 /* Only returned when kSSLSessionOptionBreakOnCertRequested is set */
2601 case errSSLClientCertRequested:
2602 failf(data, "The server has requested a client certificate");
2603 break;
2604 #endif
2605 #if CURL_BUILD_MAC_10_9
2606 /* Alias for errSSLLast, end of error range */
2607 case errSSLUnexpectedRecord:
2608 failf(data, "Unexpected (skipped) record in DTLS");
2609 break;
2610 #endif
2611 default:
2612 /* May also return codes listed in Security Framework Result Codes */
2613 failf(data, "Unknown SSL protocol error in connection to %s:%d",
2614 hostname, err);
2615 break;
2616 }
2617 return CURLE_SSL_CONNECT_ERROR;
2618 }
2619 else {
2620 /* we have been connected fine, we're not waiting for anything else. */
2621 connssl->connecting_state = ssl_connect_3;
2622
2623 #ifdef SECTRANSP_PINNEDPUBKEY
2624 if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
2625 CURLcode result = pkp_pin_peer_pubkey(data, backend->ssl_ctx,
2626 data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
2627 if(result) {
2628 failf(data, "SSL: public key does not match pinned public key!");
2629 return result;
2630 }
2631 }
2632 #endif /* SECTRANSP_PINNEDPUBKEY */
2633
2634 /* Informational message */
2635 (void)SSLGetNegotiatedCipher(backend->ssl_ctx, &cipher);
2636 (void)SSLGetNegotiatedProtocolVersion(backend->ssl_ctx, &protocol);
2637 switch(protocol) {
2638 case kSSLProtocol2:
2639 infof(data, "SSL 2.0 connection using %s\n",
2640 SSLCipherNameForNumber(cipher));
2641 break;
2642 case kSSLProtocol3:
2643 infof(data, "SSL 3.0 connection using %s\n",
2644 SSLCipherNameForNumber(cipher));
2645 break;
2646 case kTLSProtocol1:
2647 infof(data, "TLS 1.0 connection using %s\n",
2648 TLSCipherNameForNumber(cipher));
2649 break;
2650 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2651 case kTLSProtocol11:
2652 infof(data, "TLS 1.1 connection using %s\n",
2653 TLSCipherNameForNumber(cipher));
2654 break;
2655 case kTLSProtocol12:
2656 infof(data, "TLS 1.2 connection using %s\n",
2657 TLSCipherNameForNumber(cipher));
2658 break;
2659 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2660 #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
2661 case kTLSProtocol13:
2662 infof(data, "TLS 1.3 connection using %s\n",
2663 TLSCipherNameForNumber(cipher));
2664 break;
2665 #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
2666 default:
2667 infof(data, "Unknown protocol connection\n");
2668 break;
2669 }
2670
2671 #if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
2672 if(conn->bits.tls_enable_alpn) {
2673 if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
2674 CFArrayRef alpnArr = NULL;
2675 CFStringRef chosenProtocol = NULL;
2676 err = SSLCopyALPNProtocols(backend->ssl_ctx, &alpnArr);
2677
2678 if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1)
2679 chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0);
2680
2681 #ifdef USE_NGHTTP2
2682 if(chosenProtocol &&
2683 !CFStringCompare(chosenProtocol, CFSTR(NGHTTP2_PROTO_VERSION_ID),
2684 0)) {
2685 conn->negnpn = CURL_HTTP_VERSION_2;
2686 }
2687 else
2688 #endif
2689 if(chosenProtocol &&
2690 !CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) {
2691 conn->negnpn = CURL_HTTP_VERSION_1_1;
2692 }
2693 else
2694 infof(data, "ALPN, server did not agree to a protocol\n");
2695
2696 Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ?
2697 BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
2698
2699 /* chosenProtocol is a reference to the string within alpnArr
2700 and doesn't need to be freed separately */
2701 if(alpnArr)
2702 CFRelease(alpnArr);
2703 }
2704 }
2705 #endif
2706
2707 return CURLE_OK;
2708 }
2709 }
2710
2711 #ifndef CURL_DISABLE_VERBOSE_STRINGS
2712 /* This should be called during step3 of the connection at the earliest */
2713 static void
2714 show_verbose_server_cert(struct connectdata *conn,
2715 int sockindex)
2716 {
2717 struct Curl_easy *data = conn->data;
2718 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2719 struct ssl_backend_data *backend = connssl->backend;
2720 CFArrayRef server_certs = NULL;
2721 SecCertificateRef server_cert;
2722 OSStatus err;
2723 CFIndex i, count;
2724 SecTrustRef trust = NULL;
2725
2726 if(!backend->ssl_ctx)
2727 return;
2728
2729 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
2730 #if CURL_BUILD_IOS
2731 #pragma unused(server_certs)
2732 err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
2733 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2734 a null trust, so be on guard for that: */
2735 if(err == noErr && trust) {
2736 count = SecTrustGetCertificateCount(trust);
2737 for(i = 0L ; i < count ; i++) {
2738 CURLcode result;
2739 char *certp;
2740 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2741 result = CopyCertSubject(data, server_cert, &certp);
2742 if(!result) {
2743 infof(data, "Server certificate: %s\n", certp);
2744 free(certp);
2745 }
2746 }
2747 CFRelease(trust);
2748 }
2749 #else
2750 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
2751 The function SecTrustGetCertificateAtIndex() is officially present
2752 in Lion, but it is unfortunately also present in Snow Leopard as
2753 private API and doesn't work as expected. So we have to look for
2754 a different symbol to make sure this code is only executed under
2755 Lion or later. */
2756 if(SecTrustEvaluateAsync != NULL) {
2757 #pragma unused(server_certs)
2758 err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
2759 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2760 a null trust, so be on guard for that: */
2761 if(err == noErr && trust) {
2762 count = SecTrustGetCertificateCount(trust);
2763 for(i = 0L ; i < count ; i++) {
2764 char *certp;
2765 CURLcode result;
2766 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2767 result = CopyCertSubject(data, server_cert, &certp);
2768 if(!result) {
2769 infof(data, "Server certificate: %s\n", certp);
2770 free(certp);
2771 }
2772 }
2773 CFRelease(trust);
2774 }
2775 }
2776 else {
2777 #if CURL_SUPPORT_MAC_10_8
2778 err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
2779 /* Just in case SSLCopyPeerCertificates() returns null too... */
2780 if(err == noErr && server_certs) {
2781 count = CFArrayGetCount(server_certs);
2782 for(i = 0L ; i < count ; i++) {
2783 char *certp;
2784 CURLcode result;
2785 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
2786 i);
2787 result = CopyCertSubject(data, server_cert, &certp);
2788 if(!result) {
2789 infof(data, "Server certificate: %s\n", certp);
2790 free(certp);
2791 }
2792 }
2793 CFRelease(server_certs);
2794 }
2795 #endif /* CURL_SUPPORT_MAC_10_8 */
2796 }
2797 #endif /* CURL_BUILD_IOS */
2798 #else
2799 #pragma unused(trust)
2800 err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
2801 if(err == noErr) {
2802 count = CFArrayGetCount(server_certs);
2803 for(i = 0L ; i < count ; i++) {
2804 CURLcode result;
2805 char *certp;
2806 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
2807 result = CopyCertSubject(data, server_cert, &certp);
2808 if(!result) {
2809 infof(data, "Server certificate: %s\n", certp);
2810 free(certp);
2811 }
2812 }
2813 CFRelease(server_certs);
2814 }
2815 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
2816 }
2817 #endif /* !CURL_DISABLE_VERBOSE_STRINGS */
2818
2819 static CURLcode
2820 sectransp_connect_step3(struct connectdata *conn,
2821 int sockindex)
2822 {
2823 struct Curl_easy *data = conn->data;
2824 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2825
2826 /* There is no step 3!
2827 * Well, okay, if verbose mode is on, let's print the details of the
2828 * server certificates. */
2829 #ifndef CURL_DISABLE_VERBOSE_STRINGS
2830 if(data->set.verbose)
2831 show_verbose_server_cert(conn, sockindex);
2832 #endif
2833
2834 connssl->connecting_state = ssl_connect_done;
2835 return CURLE_OK;
2836 }
2837
2838 static Curl_recv sectransp_recv;
2839 static Curl_send sectransp_send;
2840
2841 static CURLcode
2842 sectransp_connect_common(struct connectdata *conn,
2843 int sockindex,
2844 bool nonblocking,
2845 bool *done)
2846 {
2847 CURLcode result;
2848 struct Curl_easy *data = conn->data;
2849 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2850 curl_socket_t sockfd = conn->sock[sockindex];
2851 int what;
2852
2853 /* check if the connection has already been established */
2854 if(ssl_connection_complete == connssl->state) {
2855 *done = TRUE;
2856 return CURLE_OK;
2857 }
2858
2859 if(ssl_connect_1 == connssl->connecting_state) {
2860 /* Find out how much more time we're allowed */
2861 const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
2862
2863 if(timeout_ms < 0) {
2864 /* no need to continue if time already is up */
2865 failf(data, "SSL connection timeout");
2866 return CURLE_OPERATION_TIMEDOUT;
2867 }
2868
2869 result = sectransp_connect_step1(conn, sockindex);
2870 if(result)
2871 return result;
2872 }
2873
2874 while(ssl_connect_2 == connssl->connecting_state ||
2875 ssl_connect_2_reading == connssl->connecting_state ||
2876 ssl_connect_2_writing == connssl->connecting_state) {
2877
2878 /* check allowed time left */
2879 const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
2880
2881 if(timeout_ms < 0) {
2882 /* no need to continue if time already is up */
2883 failf(data, "SSL connection timeout");
2884 return CURLE_OPERATION_TIMEDOUT;
2885 }
2886
2887 /* if ssl is expecting something, check if it's available. */
2888 if(connssl->connecting_state == ssl_connect_2_reading ||
2889 connssl->connecting_state == ssl_connect_2_writing) {
2890
2891 curl_socket_t writefd = ssl_connect_2_writing ==
2892 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2893 curl_socket_t readfd = ssl_connect_2_reading ==
2894 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2895
2896 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
2897 nonblocking ? 0 : timeout_ms);
2898 if(what < 0) {
2899 /* fatal error */
2900 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2901 return CURLE_SSL_CONNECT_ERROR;
2902 }
2903 else if(0 == what) {
2904 if(nonblocking) {
2905 *done = FALSE;
2906 return CURLE_OK;
2907 }
2908 else {
2909 /* timeout */
2910 failf(data, "SSL connection timeout");
2911 return CURLE_OPERATION_TIMEDOUT;
2912 }
2913 }
2914 /* socket is readable or writable */
2915 }
2916
2917 /* Run transaction, and return to the caller if it failed or if this
2918 * connection is done nonblocking and this loop would execute again. This
2919 * permits the owner of a multi handle to abort a connection attempt
2920 * before step2 has completed while ensuring that a client using select()
2921 * or epoll() will always have a valid fdset to wait on.
2922 */
2923 result = sectransp_connect_step2(conn, sockindex);
2924 if(result || (nonblocking &&
2925 (ssl_connect_2 == connssl->connecting_state ||
2926 ssl_connect_2_reading == connssl->connecting_state ||
2927 ssl_connect_2_writing == connssl->connecting_state)))
2928 return result;
2929
2930 } /* repeat step2 until all transactions are done. */
2931
2932
2933 if(ssl_connect_3 == connssl->connecting_state) {
2934 result = sectransp_connect_step3(conn, sockindex);
2935 if(result)
2936 return result;
2937 }
2938
2939 if(ssl_connect_done == connssl->connecting_state) {
2940 connssl->state = ssl_connection_complete;
2941 conn->recv[sockindex] = sectransp_recv;
2942 conn->send[sockindex] = sectransp_send;
2943 *done = TRUE;
2944 }
2945 else
2946 *done = FALSE;
2947
2948 /* Reset our connect state machine */
2949 connssl->connecting_state = ssl_connect_1;
2950
2951 return CURLE_OK;
2952 }
2953
2954 static CURLcode Curl_sectransp_connect_nonblocking(struct connectdata *conn,
2955 int sockindex, bool *done)
2956 {
2957 return sectransp_connect_common(conn, sockindex, TRUE, done);
2958 }
2959
2960 static CURLcode Curl_sectransp_connect(struct connectdata *conn, int sockindex)
2961 {
2962 CURLcode result;
2963 bool done = FALSE;
2964
2965 result = sectransp_connect_common(conn, sockindex, FALSE, &done);
2966
2967 if(result)
2968 return result;
2969
2970 DEBUGASSERT(done);
2971
2972 return CURLE_OK;
2973 }
2974
2975 static void Curl_sectransp_close(struct connectdata *conn, int sockindex)
2976 {
2977 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2978 struct ssl_backend_data *backend = connssl->backend;
2979
2980 if(backend->ssl_ctx) {
2981 (void)SSLClose(backend->ssl_ctx);
2982 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2983 if(SSLCreateContext != NULL)
2984 CFRelease(backend->ssl_ctx);
2985 #if CURL_SUPPORT_MAC_10_8
2986 else
2987 (void)SSLDisposeContext(backend->ssl_ctx);
2988 #endif /* CURL_SUPPORT_MAC_10_8 */
2989 #else
2990 (void)SSLDisposeContext(backend->ssl_ctx);
2991 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2992 backend->ssl_ctx = NULL;
2993 }
2994 backend->ssl_sockfd = 0;
2995 }
2996
2997 static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex)
2998 {
2999 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3000 struct ssl_backend_data *backend = connssl->backend;
3001 struct Curl_easy *data = conn->data;
3002 ssize_t nread;
3003 int what;
3004 int rc;
3005 char buf[120];
3006
3007 if(!backend->ssl_ctx)
3008 return 0;
3009
3010 #ifndef CURL_DISABLE_FTP
3011 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
3012 return 0;
3013 #endif
3014
3015 Curl_sectransp_close(conn, sockindex);
3016
3017 rc = 0;
3018
3019 what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
3020
3021 for(;;) {
3022 if(what < 0) {
3023 /* anything that gets here is fatally bad */
3024 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
3025 rc = -1;
3026 break;
3027 }
3028
3029 if(!what) { /* timeout */
3030 failf(data, "SSL shutdown timeout");
3031 break;
3032 }
3033
3034 /* Something to read, let's do it and hope that it is the close
3035 notify alert from the server. No way to SSL_Read now, so use read(). */
3036
3037 nread = read(conn->sock[sockindex], buf, sizeof(buf));
3038
3039 if(nread < 0) {
3040 failf(data, "read: %s", strerror(errno));
3041 rc = -1;
3042 }
3043
3044 if(nread <= 0)
3045 break;
3046
3047 what = SOCKET_READABLE(conn->sock[sockindex], 0);
3048 }
3049
3050 return rc;
3051 }
3052
3053 static void Curl_sectransp_session_free(void *ptr)
3054 {
3055 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
3056 cached session ID inside the Security framework. There is a private
3057 function that does this, but I don't want to have to explain to you why I
3058 got your application rejected from the App Store due to the use of a
3059 private API, so the best we can do is free up our own char array that we
3060 created way back in sectransp_connect_step1... */
3061 Curl_safefree(ptr);
3062 }
3063
3064 static size_t Curl_sectransp_version(char *buffer, size_t size)
3065 {
3066 return msnprintf(buffer, size, "SecureTransport");
3067 }
3068
3069 /*
3070 * This function uses SSLGetSessionState to determine connection status.
3071 *
3072 * Return codes:
3073 * 1 means the connection is still in place
3074 * 0 means the connection has been closed
3075 * -1 means the connection status is unknown
3076 */
3077 static int Curl_sectransp_check_cxn(struct connectdata *conn)
3078 {
3079 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
3080 struct ssl_backend_data *backend = connssl->backend;
3081 OSStatus err;
3082 SSLSessionState state;
3083
3084 if(backend->ssl_ctx) {
3085 err = SSLGetSessionState(backend->ssl_ctx, &state);
3086 if(err == noErr)
3087 return state == kSSLConnected || state == kSSLHandshake;
3088 return -1;
3089 }
3090 return 0;
3091 }
3092
3093 static bool Curl_sectransp_data_pending(const struct connectdata *conn,
3094 int connindex)
3095 {
3096 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
3097 struct ssl_backend_data *backend = connssl->backend;
3098 OSStatus err;
3099 size_t buffer;
3100
3101 if(backend->ssl_ctx) { /* SSL is in use */
3102 err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer);
3103 if(err == noErr)
3104 return buffer > 0UL;
3105 return false;
3106 }
3107 else
3108 return false;
3109 }
3110
3111 static CURLcode Curl_sectransp_random(struct Curl_easy *data UNUSED_PARAM,
3112 unsigned char *entropy, size_t length)
3113 {
3114 /* arc4random_buf() isn't available on cats older than Lion, so let's
3115 do this manually for the benefit of the older cats. */
3116 size_t i;
3117 u_int32_t random_number = 0;
3118
3119 (void)data;
3120
3121 for(i = 0 ; i < length ; i++) {
3122 if(i % sizeof(u_int32_t) == 0)
3123 random_number = arc4random();
3124 entropy[i] = random_number & 0xFF;
3125 random_number >>= 8;
3126 }
3127 i = random_number = 0;
3128 return CURLE_OK;
3129 }
3130
3131 static CURLcode Curl_sectransp_md5sum(unsigned char *tmp, /* input */
3132 size_t tmplen,
3133 unsigned char *md5sum, /* output */
3134 size_t md5len)
3135 {
3136 (void)md5len;
3137 (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
3138 return CURLE_OK;
3139 }
3140
3141 static CURLcode Curl_sectransp_sha256sum(const unsigned char *tmp, /* input */
3142 size_t tmplen,
3143 unsigned char *sha256sum, /* output */
3144 size_t sha256len)
3145 {
3146 assert(sha256len >= CURL_SHA256_DIGEST_LENGTH);
3147 (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum);
3148 return CURLE_OK;
3149 }
3150
3151 static bool Curl_sectransp_false_start(void)
3152 {
3153 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
3154 if(SSLSetSessionOption != NULL)
3155 return TRUE;
3156 #endif
3157 return FALSE;
3158 }
3159
3160 static ssize_t sectransp_send(struct connectdata *conn,
3161 int sockindex,
3162 const void *mem,
3163 size_t len,
3164 CURLcode *curlcode)
3165 {
3166 /*struct Curl_easy *data = conn->data;*/
3167 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3168 struct ssl_backend_data *backend = connssl->backend;
3169 size_t processed = 0UL;
3170 OSStatus err;
3171
3172 /* The SSLWrite() function works a little differently than expected. The
3173 fourth argument (processed) is currently documented in Apple's
3174 documentation as: "On return, the length, in bytes, of the data actually
3175 written."
3176
3177 Now, one could interpret that as "written to the socket," but actually,
3178 it returns the amount of data that was written to a buffer internal to
3179 the SSLContextRef instead. So it's possible for SSLWrite() to return
3180 errSSLWouldBlock and a number of bytes "written" because those bytes were
3181 encrypted and written to a buffer, not to the socket.
3182
3183 So if this happens, then we need to keep calling SSLWrite() over and
3184 over again with no new data until it quits returning errSSLWouldBlock. */
3185
3186 /* Do we have buffered data to write from the last time we were called? */
3187 if(backend->ssl_write_buffered_length) {
3188 /* Write the buffered data: */
3189 err = SSLWrite(backend->ssl_ctx, NULL, 0UL, &processed);
3190 switch(err) {
3191 case noErr:
3192 /* processed is always going to be 0 because we didn't write to
3193 the buffer, so return how much was written to the socket */
3194 processed = backend->ssl_write_buffered_length;
3195 backend->ssl_write_buffered_length = 0UL;
3196 break;
3197 case errSSLWouldBlock: /* argh, try again */
3198 *curlcode = CURLE_AGAIN;
3199 return -1L;
3200 default:
3201 failf(conn->data, "SSLWrite() returned error %d", err);
3202 *curlcode = CURLE_SEND_ERROR;
3203 return -1L;
3204 }
3205 }
3206 else {
3207 /* We've got new data to write: */
3208 err = SSLWrite(backend->ssl_ctx, mem, len, &processed);
3209 if(err != noErr) {
3210 switch(err) {
3211 case errSSLWouldBlock:
3212 /* Data was buffered but not sent, we have to tell the caller
3213 to try sending again, and remember how much was buffered */
3214 backend->ssl_write_buffered_length = len;
3215 *curlcode = CURLE_AGAIN;
3216 return -1L;
3217 default:
3218 failf(conn->data, "SSLWrite() returned error %d", err);
3219 *curlcode = CURLE_SEND_ERROR;
3220 return -1L;
3221 }
3222 }
3223 }
3224 return (ssize_t)processed;
3225 }
3226
3227 static ssize_t sectransp_recv(struct connectdata *conn,
3228 int num,
3229 char *buf,
3230 size_t buffersize,
3231 CURLcode *curlcode)
3232 {
3233 /*struct Curl_easy *data = conn->data;*/
3234 struct ssl_connect_data *connssl = &conn->ssl[num];
3235 struct ssl_backend_data *backend = connssl->backend;
3236 size_t processed = 0UL;
3237 OSStatus err;
3238
3239 again:
3240 err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed);
3241
3242 if(err != noErr) {
3243 switch(err) {
3244 case errSSLWouldBlock: /* return how much we read (if anything) */
3245 if(processed)
3246 return (ssize_t)processed;
3247 *curlcode = CURLE_AGAIN;
3248 return -1L;
3249 break;
3250
3251 /* errSSLClosedGraceful - server gracefully shut down the SSL session
3252 errSSLClosedNoNotify - server hung up on us instead of sending a
3253 closure alert notice, read() is returning 0
3254 Either way, inform the caller that the server disconnected. */
3255 case errSSLClosedGraceful:
3256 case errSSLClosedNoNotify:
3257 *curlcode = CURLE_OK;
3258 return -1L;
3259 break;
3260
3261 /* The below is errSSLPeerAuthCompleted; it's not defined in
3262 Leopard's headers */
3263 case -9841:
3264 if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
3265 CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), conn->data,
3266 backend->ssl_ctx);
3267 if(result)
3268 return result;
3269 }
3270 goto again;
3271 default:
3272 failf(conn->data, "SSLRead() return error %d", err);
3273 *curlcode = CURLE_RECV_ERROR;
3274 return -1L;
3275 break;
3276 }
3277 }
3278 return (ssize_t)processed;
3279 }
3280
3281 static void *Curl_sectransp_get_internals(struct ssl_connect_data *connssl,
3282 CURLINFO info UNUSED_PARAM)
3283 {
3284 struct ssl_backend_data *backend = connssl->backend;
3285 (void)info;
3286 return backend->ssl_ctx;
3287 }
3288
3289 const struct Curl_ssl Curl_ssl_sectransp = {
3290 { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */
3291
3292 #ifdef SECTRANSP_PINNEDPUBKEY
3293 SSLSUPP_PINNEDPUBKEY,
3294 #else
3295 0,
3296 #endif /* SECTRANSP_PINNEDPUBKEY */
3297
3298 sizeof(struct ssl_backend_data),
3299
3300 Curl_none_init, /* init */
3301 Curl_none_cleanup, /* cleanup */
3302 Curl_sectransp_version, /* version */
3303 Curl_sectransp_check_cxn, /* check_cxn */
3304 Curl_sectransp_shutdown, /* shutdown */
3305 Curl_sectransp_data_pending, /* data_pending */
3306 Curl_sectransp_random, /* random */
3307 Curl_none_cert_status_request, /* cert_status_request */
3308 Curl_sectransp_connect, /* connect */
3309 Curl_sectransp_connect_nonblocking, /* connect_nonblocking */
3310 Curl_sectransp_get_internals, /* get_internals */
3311 Curl_sectransp_close, /* close_one */
3312 Curl_none_close_all, /* close_all */
3313 Curl_sectransp_session_free, /* session_free */
3314 Curl_none_set_engine, /* set_engine */
3315 Curl_none_set_engine_default, /* set_engine_default */
3316 Curl_none_engines_list, /* engines_list */
3317 Curl_sectransp_false_start, /* false_start */
3318 Curl_sectransp_md5sum, /* md5sum */
3319 Curl_sectransp_sha256sum /* sha256sum */
3320 };
3321
3322 #ifdef __clang__
3323 #pragma clang diagnostic pop
3324 #endif
3325
3326 #endif /* USE_SECTRANSP */
3327