Annotation of embedaddon/curl/lib/vtls/sectransp.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>