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