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