File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / vtls / sectransp.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:15 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    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>