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