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