darwinssl.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
00009  * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00010  *
00011  * This software is licensed as described in the file COPYING, which
00012  * you should have received as part of this distribution. The terms
00013  * are also available at https://curl.haxx.se/docs/copyright.html.
00014  *
00015  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00016  * copies of the Software, and permit persons to whom the Software is
00017  * furnished to do so, under the terms of the COPYING file.
00018  *
00019  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00020  * KIND, either express or implied.
00021  *
00022  ***************************************************************************/
00023 
00024 /*
00025  * Source file for all iOS and Mac OS X SecureTransport-specific code for the
00026  * TLS/SSL layer. No code but vtls.c should ever call or use these functions.
00027  */
00028 
00029 #include "curl_setup.h"
00030 
00031 #include "urldata.h" /* for the Curl_easy definition */
00032 #include "curl_base64.h"
00033 #include "strtok.h"
00034 
00035 #ifdef USE_DARWINSSL
00036 
00037 #ifdef HAVE_LIMITS_H
00038 #include <limits.h>
00039 #endif
00040 
00041 #include <Security/Security.h>
00042 #include <Security/SecureTransport.h>
00043 #include <CoreFoundation/CoreFoundation.h>
00044 #include <CommonCrypto/CommonDigest.h>
00045 
00046 /* The Security framework has changed greatly between iOS and different OS X
00047    versions, and we will try to support as many of them as we can (back to
00048    Leopard and iOS 5) by using macros and weak-linking.
00049 
00050    IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
00051    you must build this project against the 10.8 SDK or later. */
00052 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
00053 
00054 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
00055 #error "The darwinssl back-end requires Leopard or later."
00056 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
00057 
00058 #define CURL_BUILD_IOS 0
00059 #define CURL_BUILD_IOS_7 0
00060 #define CURL_BUILD_MAC 1
00061 /* This is the maximum API level we are allowed to use when building: */
00062 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
00063 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
00064 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
00065 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
00066 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
00067 /* These macros mean "the following code is present to allow runtime backward
00068    compatibility with at least this cat or earlier":
00069    (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
00070    environmental variable.) */
00071 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
00072 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
00073 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
00074 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
00075 #define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
00076 
00077 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
00078 #define CURL_BUILD_IOS 1
00079 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
00080 #define CURL_BUILD_MAC 0
00081 #define CURL_BUILD_MAC_10_5 0
00082 #define CURL_BUILD_MAC_10_6 0
00083 #define CURL_BUILD_MAC_10_7 0
00084 #define CURL_BUILD_MAC_10_8 0
00085 #define CURL_SUPPORT_MAC_10_5 0
00086 #define CURL_SUPPORT_MAC_10_6 0
00087 #define CURL_SUPPORT_MAC_10_7 0
00088 #define CURL_SUPPORT_MAC_10_8 0
00089 #define CURL_SUPPORT_MAC_10_9 0
00090 
00091 #else
00092 #error "The darwinssl back-end requires iOS or OS X."
00093 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
00094 
00095 #if CURL_BUILD_MAC
00096 #include <sys/sysctl.h>
00097 #endif /* CURL_BUILD_MAC */
00098 
00099 #include "urldata.h"
00100 #include "sendf.h"
00101 #include "inet_pton.h"
00102 #include "connect.h"
00103 #include "select.h"
00104 #include "vtls.h"
00105 #include "darwinssl.h"
00106 #include "curl_printf.h"
00107 
00108 #include "curl_memory.h"
00109 /* The last #include file should be: */
00110 #include "memdebug.h"
00111 
00112 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
00113 #define ioErr -36
00114 #define paramErr -50
00115 
00116 /* The following two functions were ripped from Apple sample code,
00117  * with some modifications: */
00118 static OSStatus SocketRead(SSLConnectionRef connection,
00119                            void *data,          /* owned by
00120                                                  * caller, data
00121                                                  * RETURNED */
00122                            size_t *dataLength)  /* IN/OUT */
00123 {
00124   size_t bytesToGo = *dataLength;
00125   size_t initLen = bytesToGo;
00126   UInt8 *currData = (UInt8 *)data;
00127   /*int sock = *(int *)connection;*/
00128   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
00129   int sock = connssl->ssl_sockfd;
00130   OSStatus rtn = noErr;
00131   size_t bytesRead;
00132   ssize_t rrtn;
00133   int theErr;
00134 
00135   *dataLength = 0;
00136 
00137   for(;;) {
00138     bytesRead = 0;
00139     rrtn = read(sock, currData, bytesToGo);
00140     if(rrtn <= 0) {
00141       /* this is guesswork... */
00142       theErr = errno;
00143       if(rrtn == 0) { /* EOF = server hung up */
00144         /* the framework will turn this into errSSLClosedNoNotify */
00145         rtn = errSSLClosedGraceful;
00146       }
00147       else /* do the switch */
00148         switch(theErr) {
00149           case ENOENT:
00150             /* connection closed */
00151             rtn = errSSLClosedGraceful;
00152             break;
00153           case ECONNRESET:
00154             rtn = errSSLClosedAbort;
00155             break;
00156           case EAGAIN:
00157             rtn = errSSLWouldBlock;
00158             connssl->ssl_direction = false;
00159             break;
00160           default:
00161             rtn = ioErr;
00162             break;
00163         }
00164       break;
00165     }
00166     else {
00167       bytesRead = rrtn;
00168     }
00169     bytesToGo -= bytesRead;
00170     currData  += bytesRead;
00171 
00172     if(bytesToGo == 0) {
00173       /* filled buffer with incoming data, done */
00174       break;
00175     }
00176   }
00177   *dataLength = initLen - bytesToGo;
00178 
00179   return rtn;
00180 }
00181 
00182 static OSStatus SocketWrite(SSLConnectionRef connection,
00183                             const void *data,
00184                             size_t *dataLength)  /* IN/OUT */
00185 {
00186   size_t bytesSent = 0;
00187   /*int sock = *(int *)connection;*/
00188   struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
00189   int sock = connssl->ssl_sockfd;
00190   ssize_t length;
00191   size_t dataLen = *dataLength;
00192   const UInt8 *dataPtr = (UInt8 *)data;
00193   OSStatus ortn;
00194   int theErr;
00195 
00196   *dataLength = 0;
00197 
00198   do {
00199     length = write(sock,
00200                    (char *)dataPtr + bytesSent,
00201                    dataLen - bytesSent);
00202   } while((length > 0) &&
00203            ( (bytesSent += length) < dataLen) );
00204 
00205   if(length <= 0) {
00206     theErr = errno;
00207     if(theErr == EAGAIN) {
00208       ortn = errSSLWouldBlock;
00209       connssl->ssl_direction = true;
00210     }
00211     else {
00212       ortn = ioErr;
00213     }
00214   }
00215   else {
00216     ortn = noErr;
00217   }
00218   *dataLength = bytesSent;
00219   return ortn;
00220 }
00221 
00222 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher)
00223 {
00224   switch(cipher) {
00225     /* SSL version 3.0 */
00226     case SSL_RSA_WITH_NULL_MD5:
00227       return "SSL_RSA_WITH_NULL_MD5";
00228       break;
00229     case SSL_RSA_WITH_NULL_SHA:
00230       return "SSL_RSA_WITH_NULL_SHA";
00231       break;
00232     case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
00233       return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
00234       break;
00235     case SSL_RSA_WITH_RC4_128_MD5:
00236       return "SSL_RSA_WITH_RC4_128_MD5";
00237       break;
00238     case SSL_RSA_WITH_RC4_128_SHA:
00239       return "SSL_RSA_WITH_RC4_128_SHA";
00240       break;
00241     case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
00242       return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
00243       break;
00244     case SSL_RSA_WITH_IDEA_CBC_SHA:
00245       return "SSL_RSA_WITH_IDEA_CBC_SHA";
00246       break;
00247     case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
00248       return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
00249       break;
00250     case SSL_RSA_WITH_DES_CBC_SHA:
00251       return "SSL_RSA_WITH_DES_CBC_SHA";
00252       break;
00253     case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
00254       return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
00255       break;
00256     case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
00257       return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
00258       break;
00259     case SSL_DH_DSS_WITH_DES_CBC_SHA:
00260       return "SSL_DH_DSS_WITH_DES_CBC_SHA";
00261       break;
00262     case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
00263       return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
00264       break;
00265     case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
00266       return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
00267       break;
00268     case SSL_DH_RSA_WITH_DES_CBC_SHA:
00269       return "SSL_DH_RSA_WITH_DES_CBC_SHA";
00270       break;
00271     case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
00272       return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
00273       break;
00274     case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
00275       return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
00276       break;
00277     case SSL_DHE_DSS_WITH_DES_CBC_SHA:
00278       return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
00279       break;
00280     case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
00281       return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
00282       break;
00283     case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
00284       return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
00285       break;
00286     case SSL_DHE_RSA_WITH_DES_CBC_SHA:
00287       return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
00288       break;
00289     case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
00290       return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
00291       break;
00292     case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
00293       return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
00294       break;
00295     case SSL_DH_anon_WITH_RC4_128_MD5:
00296       return "SSL_DH_anon_WITH_RC4_128_MD5";
00297       break;
00298     case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
00299       return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
00300       break;
00301     case SSL_DH_anon_WITH_DES_CBC_SHA:
00302       return "SSL_DH_anon_WITH_DES_CBC_SHA";
00303       break;
00304     case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
00305       return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
00306       break;
00307     case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
00308       return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
00309       break;
00310     case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
00311       return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
00312       break;
00313     /* TLS 1.0 with AES (RFC 3268)
00314        (Apparently these are used in SSLv3 implementations as well.) */
00315     case TLS_RSA_WITH_AES_128_CBC_SHA:
00316       return "TLS_RSA_WITH_AES_128_CBC_SHA";
00317       break;
00318     case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
00319       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
00320       break;
00321     case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
00322       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
00323       break;
00324     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
00325       return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
00326       break;
00327     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
00328       return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
00329       break;
00330     case TLS_DH_anon_WITH_AES_128_CBC_SHA:
00331       return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
00332       break;
00333     case TLS_RSA_WITH_AES_256_CBC_SHA:
00334       return "TLS_RSA_WITH_AES_256_CBC_SHA";
00335       break;
00336     case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
00337       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
00338       break;
00339     case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
00340       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
00341       break;
00342     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
00343       return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
00344       break;
00345     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
00346       return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
00347       break;
00348     case TLS_DH_anon_WITH_AES_256_CBC_SHA:
00349       return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
00350       break;
00351     /* SSL version 2.0 */
00352     case SSL_RSA_WITH_RC2_CBC_MD5:
00353       return "SSL_RSA_WITH_RC2_CBC_MD5";
00354       break;
00355     case SSL_RSA_WITH_IDEA_CBC_MD5:
00356       return "SSL_RSA_WITH_IDEA_CBC_MD5";
00357       break;
00358     case SSL_RSA_WITH_DES_CBC_MD5:
00359       return "SSL_RSA_WITH_DES_CBC_MD5";
00360       break;
00361     case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
00362       return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
00363       break;
00364   }
00365   return "SSL_NULL_WITH_NULL_NULL";
00366 }
00367 
00368 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
00369 {
00370   switch(cipher) {
00371     /* TLS 1.0 with AES (RFC 3268) */
00372     case TLS_RSA_WITH_AES_128_CBC_SHA:
00373       return "TLS_RSA_WITH_AES_128_CBC_SHA";
00374       break;
00375     case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
00376       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
00377       break;
00378     case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
00379       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
00380       break;
00381     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
00382       return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
00383       break;
00384     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
00385       return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
00386       break;
00387     case TLS_DH_anon_WITH_AES_128_CBC_SHA:
00388       return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
00389       break;
00390     case TLS_RSA_WITH_AES_256_CBC_SHA:
00391       return "TLS_RSA_WITH_AES_256_CBC_SHA";
00392       break;
00393     case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
00394       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
00395       break;
00396     case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
00397       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
00398       break;
00399     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
00400       return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
00401       break;
00402     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
00403       return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
00404       break;
00405     case TLS_DH_anon_WITH_AES_256_CBC_SHA:
00406       return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
00407       break;
00408 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
00409     /* TLS 1.0 with ECDSA (RFC 4492) */
00410     case TLS_ECDH_ECDSA_WITH_NULL_SHA:
00411       return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
00412       break;
00413     case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
00414       return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
00415       break;
00416     case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
00417       return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
00418       break;
00419     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
00420       return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
00421       break;
00422     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
00423       return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
00424       break;
00425     case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
00426       return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
00427       break;
00428     case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
00429       return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
00430       break;
00431     case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
00432       return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
00433       break;
00434     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
00435       return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
00436       break;
00437     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
00438       return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
00439       break;
00440     case TLS_ECDH_RSA_WITH_NULL_SHA:
00441       return "TLS_ECDH_RSA_WITH_NULL_SHA";
00442       break;
00443     case TLS_ECDH_RSA_WITH_RC4_128_SHA:
00444       return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
00445       break;
00446     case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
00447       return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
00448       break;
00449     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
00450       return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
00451       break;
00452     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
00453       return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
00454       break;
00455     case TLS_ECDHE_RSA_WITH_NULL_SHA:
00456       return "TLS_ECDHE_RSA_WITH_NULL_SHA";
00457       break;
00458     case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
00459       return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
00460       break;
00461     case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
00462       return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
00463       break;
00464     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
00465       return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
00466       break;
00467     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
00468       return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
00469       break;
00470     case TLS_ECDH_anon_WITH_NULL_SHA:
00471       return "TLS_ECDH_anon_WITH_NULL_SHA";
00472       break;
00473     case TLS_ECDH_anon_WITH_RC4_128_SHA:
00474       return "TLS_ECDH_anon_WITH_RC4_128_SHA";
00475       break;
00476     case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
00477       return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
00478       break;
00479     case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
00480       return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
00481       break;
00482     case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
00483       return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
00484       break;
00485 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
00486 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
00487     /* TLS 1.2 (RFC 5246) */
00488     case TLS_RSA_WITH_NULL_MD5:
00489       return "TLS_RSA_WITH_NULL_MD5";
00490       break;
00491     case TLS_RSA_WITH_NULL_SHA:
00492       return "TLS_RSA_WITH_NULL_SHA";
00493       break;
00494     case TLS_RSA_WITH_RC4_128_MD5:
00495       return "TLS_RSA_WITH_RC4_128_MD5";
00496       break;
00497     case TLS_RSA_WITH_RC4_128_SHA:
00498       return "TLS_RSA_WITH_RC4_128_SHA";
00499       break;
00500     case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
00501       return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
00502       break;
00503     case TLS_RSA_WITH_NULL_SHA256:
00504       return "TLS_RSA_WITH_NULL_SHA256";
00505       break;
00506     case TLS_RSA_WITH_AES_128_CBC_SHA256:
00507       return "TLS_RSA_WITH_AES_128_CBC_SHA256";
00508       break;
00509     case TLS_RSA_WITH_AES_256_CBC_SHA256:
00510       return "TLS_RSA_WITH_AES_256_CBC_SHA256";
00511       break;
00512     case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
00513       return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
00514       break;
00515     case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
00516       return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
00517       break;
00518     case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
00519       return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
00520       break;
00521     case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
00522       return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
00523       break;
00524     case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
00525       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
00526       break;
00527     case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
00528       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
00529       break;
00530     case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
00531       return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
00532       break;
00533     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
00534       return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
00535       break;
00536     case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
00537       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
00538       break;
00539     case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
00540       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
00541       break;
00542     case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
00543       return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
00544       break;
00545     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
00546       return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
00547       break;
00548     case TLS_DH_anon_WITH_RC4_128_MD5:
00549       return "TLS_DH_anon_WITH_RC4_128_MD5";
00550       break;
00551     case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
00552       return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
00553       break;
00554     case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
00555       return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
00556       break;
00557     case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
00558       return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
00559       break;
00560     /* TLS 1.2 with AES GCM (RFC 5288) */
00561     case TLS_RSA_WITH_AES_128_GCM_SHA256:
00562       return "TLS_RSA_WITH_AES_128_GCM_SHA256";
00563       break;
00564     case TLS_RSA_WITH_AES_256_GCM_SHA384:
00565       return "TLS_RSA_WITH_AES_256_GCM_SHA384";
00566       break;
00567     case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
00568       return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
00569       break;
00570     case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
00571       return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
00572       break;
00573     case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
00574       return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
00575       break;
00576     case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
00577       return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
00578       break;
00579     case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
00580       return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
00581       break;
00582     case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
00583       return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
00584       break;
00585     case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
00586       return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
00587       break;
00588     case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
00589       return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
00590       break;
00591     case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
00592       return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
00593       break;
00594     case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
00595       return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
00596       break;
00597     /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
00598     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
00599       return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
00600       break;
00601     case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
00602       return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
00603       break;
00604     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
00605       return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
00606       break;
00607     case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
00608       return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
00609       break;
00610     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
00611       return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
00612       break;
00613     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
00614       return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
00615       break;
00616     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
00617       return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
00618       break;
00619     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
00620       return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
00621       break;
00622     case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
00623       return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
00624       break;
00625     case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
00626       return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
00627       break;
00628     case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
00629       return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
00630       break;
00631     case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
00632       return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
00633       break;
00634     case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
00635       return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
00636       break;
00637     case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
00638       return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
00639       break;
00640     case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
00641       return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
00642       break;
00643     case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
00644       return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
00645       break;
00646     case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
00647       return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
00648       break;
00649 #else
00650     case SSL_RSA_WITH_NULL_MD5:
00651       return "TLS_RSA_WITH_NULL_MD5";
00652       break;
00653     case SSL_RSA_WITH_NULL_SHA:
00654       return "TLS_RSA_WITH_NULL_SHA";
00655       break;
00656     case SSL_RSA_WITH_RC4_128_MD5:
00657       return "TLS_RSA_WITH_RC4_128_MD5";
00658       break;
00659     case SSL_RSA_WITH_RC4_128_SHA:
00660       return "TLS_RSA_WITH_RC4_128_SHA";
00661       break;
00662     case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
00663       return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
00664       break;
00665     case SSL_DH_anon_WITH_RC4_128_MD5:
00666       return "TLS_DH_anon_WITH_RC4_128_MD5";
00667       break;
00668     case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
00669       return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
00670       break;
00671 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
00672 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
00673     /* TLS PSK (RFC 4279): */
00674     case TLS_PSK_WITH_RC4_128_SHA:
00675       return "TLS_PSK_WITH_RC4_128_SHA";
00676       break;
00677     case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
00678       return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
00679       break;
00680     case TLS_PSK_WITH_AES_128_CBC_SHA:
00681       return "TLS_PSK_WITH_AES_128_CBC_SHA";
00682       break;
00683     case TLS_PSK_WITH_AES_256_CBC_SHA:
00684       return "TLS_PSK_WITH_AES_256_CBC_SHA";
00685       break;
00686     case TLS_DHE_PSK_WITH_RC4_128_SHA:
00687       return "TLS_DHE_PSK_WITH_RC4_128_SHA";
00688       break;
00689     case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
00690       return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
00691       break;
00692     case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
00693       return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
00694       break;
00695     case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
00696       return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
00697       break;
00698     case TLS_RSA_PSK_WITH_RC4_128_SHA:
00699       return "TLS_RSA_PSK_WITH_RC4_128_SHA";
00700       break;
00701     case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
00702       return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
00703       break;
00704     case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
00705       return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
00706       break;
00707     case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
00708       return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
00709       break;
00710     /* More TLS PSK (RFC 4785): */
00711     case TLS_PSK_WITH_NULL_SHA:
00712       return "TLS_PSK_WITH_NULL_SHA";
00713       break;
00714     case TLS_DHE_PSK_WITH_NULL_SHA:
00715       return "TLS_DHE_PSK_WITH_NULL_SHA";
00716       break;
00717     case TLS_RSA_PSK_WITH_NULL_SHA:
00718       return "TLS_RSA_PSK_WITH_NULL_SHA";
00719       break;
00720     /* Even more TLS PSK (RFC 5487): */
00721     case TLS_PSK_WITH_AES_128_GCM_SHA256:
00722       return "TLS_PSK_WITH_AES_128_GCM_SHA256";
00723       break;
00724     case TLS_PSK_WITH_AES_256_GCM_SHA384:
00725       return "TLS_PSK_WITH_AES_256_GCM_SHA384";
00726       break;
00727     case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
00728       return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
00729       break;
00730     case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
00731       return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
00732       break;
00733     case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
00734       return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
00735       break;
00736     case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
00737       return "TLS_PSK_WITH_AES_256_GCM_SHA384";
00738       break;
00739     case TLS_PSK_WITH_AES_128_CBC_SHA256:
00740       return "TLS_PSK_WITH_AES_128_CBC_SHA256";
00741       break;
00742     case TLS_PSK_WITH_AES_256_CBC_SHA384:
00743       return "TLS_PSK_WITH_AES_256_CBC_SHA384";
00744       break;
00745     case TLS_PSK_WITH_NULL_SHA256:
00746       return "TLS_PSK_WITH_NULL_SHA256";
00747       break;
00748     case TLS_PSK_WITH_NULL_SHA384:
00749       return "TLS_PSK_WITH_NULL_SHA384";
00750       break;
00751     case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
00752       return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
00753       break;
00754     case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
00755       return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
00756       break;
00757     case TLS_DHE_PSK_WITH_NULL_SHA256:
00758       return "TLS_DHE_PSK_WITH_NULL_SHA256";
00759       break;
00760     case TLS_DHE_PSK_WITH_NULL_SHA384:
00761       return "TLS_RSA_PSK_WITH_NULL_SHA384";
00762       break;
00763     case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
00764       return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
00765       break;
00766     case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
00767       return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
00768       break;
00769     case TLS_RSA_PSK_WITH_NULL_SHA256:
00770       return "TLS_RSA_PSK_WITH_NULL_SHA256";
00771       break;
00772     case TLS_RSA_PSK_WITH_NULL_SHA384:
00773       return "TLS_RSA_PSK_WITH_NULL_SHA384";
00774       break;
00775 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
00776   }
00777   return "TLS_NULL_WITH_NULL_NULL";
00778 }
00779 
00780 #if CURL_BUILD_MAC
00781 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
00782 {
00783   int mib[2];
00784   char *os_version;
00785   size_t os_version_len;
00786   char *os_version_major, *os_version_minor;
00787   char *tok_buf;
00788 
00789   /* Get the Darwin kernel version from the kernel using sysctl(): */
00790   mib[0] = CTL_KERN;
00791   mib[1] = KERN_OSRELEASE;
00792   if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
00793     return;
00794   os_version = malloc(os_version_len*sizeof(char));
00795   if(!os_version)
00796     return;
00797   if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
00798     free(os_version);
00799     return;
00800   }
00801 
00802   /* Parse the version: */
00803   os_version_major = strtok_r(os_version, ".", &tok_buf);
00804   os_version_minor = strtok_r(NULL, ".", &tok_buf);
00805   *major = atoi(os_version_major);
00806   *minor = atoi(os_version_minor);
00807   free(os_version);
00808 }
00809 #endif /* CURL_BUILD_MAC */
00810 
00811 /* Apple provides a myriad of ways of getting information about a certificate
00812    into a string. Some aren't available under iOS or newer cats. So here's
00813    a unified function for getting a string describing the certificate that
00814    ought to work in all cats starting with Leopard. */
00815 CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
00816 {
00817   CFStringRef server_cert_summary = CFSTR("(null)");
00818 
00819 #if CURL_BUILD_IOS
00820   /* iOS: There's only one way to do this. */
00821   server_cert_summary = SecCertificateCopySubjectSummary(cert);
00822 #else
00823 #if CURL_BUILD_MAC_10_7
00824   /* Lion & later: Get the long description if we can. */
00825   if(SecCertificateCopyLongDescription != NULL)
00826     server_cert_summary =
00827       SecCertificateCopyLongDescription(NULL, cert, NULL);
00828   else
00829 #endif /* CURL_BUILD_MAC_10_7 */
00830 #if CURL_BUILD_MAC_10_6
00831   /* Snow Leopard: Get the certificate summary. */
00832   if(SecCertificateCopySubjectSummary != NULL)
00833     server_cert_summary = SecCertificateCopySubjectSummary(cert);
00834   else
00835 #endif /* CURL_BUILD_MAC_10_6 */
00836   /* Leopard is as far back as we go... */
00837   (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
00838 #endif /* CURL_BUILD_IOS */
00839   return server_cert_summary;
00840 }
00841 
00842 #if CURL_SUPPORT_MAC_10_6
00843 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
00844    deprecation warnings, so let's not compile this unless it's necessary: */
00845 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
00846                                                SecIdentityRef *out_c_a_k)
00847 {
00848   OSStatus status = errSecItemNotFound;
00849   SecKeychainAttributeList attr_list;
00850   SecKeychainAttribute attr;
00851   SecKeychainSearchRef search = NULL;
00852   SecCertificateRef cert = NULL;
00853 
00854   /* Set up the attribute list: */
00855   attr_list.count = 1L;
00856   attr_list.attr = &attr;
00857 
00858   /* Set up our lone search criterion: */
00859   attr.tag = kSecLabelItemAttr;
00860   attr.data = label;
00861   attr.length = (UInt32)strlen(label);
00862 
00863   /* Start searching: */
00864   status = SecKeychainSearchCreateFromAttributes(NULL,
00865                                                  kSecCertificateItemClass,
00866                                                  &attr_list,
00867                                                  &search);
00868   if(status == noErr) {
00869     status = SecKeychainSearchCopyNext(search,
00870                                        (SecKeychainItemRef *)&cert);
00871     if(status == noErr && cert) {
00872       /* If we found a certificate, does it have a private key? */
00873       status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
00874       CFRelease(cert);
00875     }
00876   }
00877 
00878   if(search)
00879     CFRelease(search);
00880   return status;
00881 }
00882 #endif /* CURL_SUPPORT_MAC_10_6 */
00883 
00884 static OSStatus CopyIdentityWithLabel(char *label,
00885                                       SecIdentityRef *out_cert_and_key)
00886 {
00887   OSStatus status = errSecItemNotFound;
00888   CFArrayRef keys_list;
00889   CFIndex keys_list_count;
00890   CFIndex i;
00891   CFStringRef common_name;
00892 
00893 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
00894   /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
00895      kSecClassIdentity was introduced in Lion. If both exist, let's use them
00896      to find the certificate. */
00897   if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
00898     CFTypeRef keys[5];
00899     CFTypeRef values[5];
00900     CFDictionaryRef query_dict;
00901     CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
00902       kCFStringEncodingUTF8);
00903 
00904     /* Set up our search criteria and expected results: */
00905     values[0] = kSecClassIdentity; /* we want a certificate and a key */
00906     keys[0] = kSecClass;
00907     values[1] = kCFBooleanTrue;    /* we want a reference */
00908     keys[1] = kSecReturnRef;
00909     values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the
00910                                     * label matching below worked correctly */
00911     keys[2] = kSecMatchLimit;
00912     /* identity searches need a SecPolicyRef in order to work */
00913     values[3] = SecPolicyCreateSSL(false, NULL);
00914     keys[3] = kSecMatchPolicy;
00915     /* match the name of the certificate (doesn't work in macOS 10.12.1) */
00916     values[4] = label_cf;
00917     keys[4] = kSecAttrLabel;
00918     query_dict = CFDictionaryCreate(NULL, (const void **)keys,
00919                                     (const void **)values, 5L,
00920                                     &kCFCopyStringDictionaryKeyCallBacks,
00921                                     &kCFTypeDictionaryValueCallBacks);
00922     CFRelease(values[3]);
00923 
00924     /* Do we have a match? */
00925     status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
00926 
00927     /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity,
00928      * we need to find the correct identity ourselves */
00929     if(status == noErr) {
00930       keys_list_count = CFArrayGetCount(keys_list);
00931       *out_cert_and_key = NULL;
00932       for(i=0; i<keys_list_count; i++) {
00933         OSStatus err = noErr;
00934         SecCertificateRef cert = NULL;
00935         *out_cert_and_key =
00936           (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
00937         err = SecIdentityCopyCertificate(*out_cert_and_key, &cert);
00938         if(err == noErr) {
00939           SecCertificateCopyCommonName(cert, &common_name);
00940           if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
00941             CFRelease(cert);
00942             CFRelease(common_name);
00943             status = noErr;
00944             break;
00945           }
00946           CFRelease(common_name);
00947         }
00948         *out_cert_and_key = NULL;
00949         status = 1;
00950         CFRelease(cert);
00951       }
00952     }
00953 
00954     CFRelease(query_dict);
00955     CFRelease(label_cf);
00956   }
00957   else {
00958 #if CURL_SUPPORT_MAC_10_6
00959     /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
00960     status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
00961 #endif /* CURL_SUPPORT_MAC_10_6 */
00962   }
00963 #elif CURL_SUPPORT_MAC_10_6
00964   /* For developers building on older cats, we have no choice but to fall back
00965      to SecKeychainSearch. */
00966   status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
00967 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
00968   return status;
00969 }
00970 
00971 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
00972                                            const char *cPassword,
00973                                            SecIdentityRef *out_cert_and_key)
00974 {
00975   OSStatus status = errSecItemNotFound;
00976   CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
00977     (const UInt8 *)cPath, strlen(cPath), false);
00978   CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
00979     cPassword, kCFStringEncodingUTF8) : NULL;
00980   CFDataRef pkcs_data = NULL;
00981 
00982   /* We can import P12 files on iOS or OS X 10.7 or later: */
00983   /* These constants are documented as having first appeared in 10.6 but they
00984      raise linker errors when used on that cat for some reason. */
00985 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
00986   if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
00987     NULL, NULL, &status)) {
00988     const void *cKeys[] = {kSecImportExportPassphrase};
00989     const void *cValues[] = {password};
00990     CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
00991       password ? 1L : 0L, NULL, NULL);
00992     CFArrayRef items = NULL;
00993 
00994     /* Here we go: */
00995     status = SecPKCS12Import(pkcs_data, options, &items);
00996     if(status == errSecSuccess && items && CFArrayGetCount(items)) {
00997       CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
00998       const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
00999         kSecImportItemIdentity);
01000 
01001       /* Retain the identity; we don't care about any other data... */
01002       CFRetain(temp_identity);
01003       *out_cert_and_key = (SecIdentityRef)temp_identity;
01004     }
01005 
01006     if(items)
01007       CFRelease(items);
01008     CFRelease(options);
01009     CFRelease(pkcs_data);
01010   }
01011 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
01012   if(password)
01013     CFRelease(password);
01014   CFRelease(pkcs_url);
01015   return status;
01016 }
01017 
01018 /* This code was borrowed from nss.c, with some modifications:
01019  * Determine whether the nickname passed in is a filename that needs to
01020  * be loaded as a PEM or a regular NSS nickname.
01021  *
01022  * returns 1 for a file
01023  * returns 0 for not a file
01024  */
01025 CF_INLINE bool is_file(const char *filename)
01026 {
01027   struct_stat st;
01028 
01029   if(filename == NULL)
01030     return false;
01031 
01032   if(stat(filename, &st) == 0)
01033     return S_ISREG(st.st_mode);
01034   return false;
01035 }
01036 
01037 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
01038                                         int sockindex)
01039 {
01040   struct Curl_easy *data = conn->data;
01041   curl_socket_t sockfd = conn->sock[sockindex];
01042   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
01043   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
01044   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
01045   char * const ssl_cert = SSL_SET_OPTION(cert);
01046   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
01047     conn->host.name;
01048   const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
01049 #ifdef ENABLE_IPV6
01050   struct in6_addr addr;
01051 #else
01052   struct in_addr addr;
01053 #endif /* ENABLE_IPV6 */
01054   size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
01055   SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
01056   OSStatus err = noErr;
01057 #if CURL_BUILD_MAC
01058   int darwinver_maj = 0, darwinver_min = 0;
01059 
01060   GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
01061 #endif /* CURL_BUILD_MAC */
01062 
01063 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
01064   if(SSLCreateContext != NULL) {  /* use the newer API if avaialble */
01065     if(connssl->ssl_ctx)
01066       CFRelease(connssl->ssl_ctx);
01067     connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
01068     if(!connssl->ssl_ctx) {
01069       failf(data, "SSL: couldn't create a context!");
01070       return CURLE_OUT_OF_MEMORY;
01071     }
01072   }
01073   else {
01074   /* The old ST API does not exist under iOS, so don't compile it: */
01075 #if CURL_SUPPORT_MAC_10_8
01076     if(connssl->ssl_ctx)
01077       (void)SSLDisposeContext(connssl->ssl_ctx);
01078     err = SSLNewContext(false, &(connssl->ssl_ctx));
01079     if(err != noErr) {
01080       failf(data, "SSL: couldn't create a context: OSStatus %d", err);
01081       return CURLE_OUT_OF_MEMORY;
01082     }
01083 #endif /* CURL_SUPPORT_MAC_10_8 */
01084   }
01085 #else
01086   if(connssl->ssl_ctx)
01087     (void)SSLDisposeContext(connssl->ssl_ctx);
01088   err = SSLNewContext(false, &(connssl->ssl_ctx));
01089   if(err != noErr) {
01090     failf(data, "SSL: couldn't create a context: OSStatus %d", err);
01091     return CURLE_OUT_OF_MEMORY;
01092   }
01093 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
01094   connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
01095 
01096   /* check to see if we've been told to use an explicit SSL/TLS version */
01097 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
01098   if(SSLSetProtocolVersionMax != NULL) {
01099     switch(conn->ssl_config.version) {
01100     case CURL_SSLVERSION_DEFAULT:
01101     case CURL_SSLVERSION_TLSv1:
01102       (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
01103       (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
01104       break;
01105     case CURL_SSLVERSION_TLSv1_0:
01106       (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
01107       (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
01108       break;
01109     case CURL_SSLVERSION_TLSv1_1:
01110       (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
01111       (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
01112       break;
01113     case CURL_SSLVERSION_TLSv1_2:
01114       (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
01115       (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
01116       break;
01117     case CURL_SSLVERSION_TLSv1_3:
01118       failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
01119       return CURLE_SSL_CONNECT_ERROR;
01120     case CURL_SSLVERSION_SSLv3:
01121       err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
01122       if(err != noErr) {
01123         failf(data, "Your version of the OS does not support SSLv3");
01124         return CURLE_SSL_CONNECT_ERROR;
01125       }
01126       (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
01127       break;
01128     case CURL_SSLVERSION_SSLv2:
01129       err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
01130       if(err != noErr) {
01131         failf(data, "Your version of the OS does not support SSLv2");
01132         return CURLE_SSL_CONNECT_ERROR;
01133       }
01134       (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
01135       break;
01136     default:
01137       failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
01138       return CURLE_SSL_CONNECT_ERROR;
01139     }
01140   }
01141   else {
01142 #if CURL_SUPPORT_MAC_10_8
01143     (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01144                                        kSSLProtocolAll,
01145                                        false);
01146     switch(conn->ssl_config.version) {
01147     case CURL_SSLVERSION_DEFAULT:
01148     case CURL_SSLVERSION_TLSv1:
01149       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01150                                          kTLSProtocol1,
01151                                          true);
01152       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01153                                          kTLSProtocol11,
01154                                          true);
01155       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01156                                          kTLSProtocol12,
01157                                          true);
01158       break;
01159     case CURL_SSLVERSION_TLSv1_0:
01160       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01161                                          kTLSProtocol1,
01162                                          true);
01163       break;
01164     case CURL_SSLVERSION_TLSv1_1:
01165       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01166                                          kTLSProtocol11,
01167                                          true);
01168       break;
01169     case CURL_SSLVERSION_TLSv1_2:
01170       (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01171                                          kTLSProtocol12,
01172                                          true);
01173       break;
01174     case CURL_SSLVERSION_TLSv1_3:
01175       failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
01176       return CURLE_SSL_CONNECT_ERROR;
01177     case CURL_SSLVERSION_SSLv3:
01178       err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01179                                          kSSLProtocol3,
01180                                          true);
01181       if(err != noErr) {
01182         failf(data, "Your version of the OS does not support SSLv3");
01183         return CURLE_SSL_CONNECT_ERROR;
01184       }
01185       break;
01186     case CURL_SSLVERSION_SSLv2:
01187       err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01188                                          kSSLProtocol2,
01189                                          true);
01190       if(err != noErr) {
01191         failf(data, "Your version of the OS does not support SSLv2");
01192         return CURLE_SSL_CONNECT_ERROR;
01193       }
01194       break;
01195     default:
01196       failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
01197       return CURLE_SSL_CONNECT_ERROR;
01198     }
01199 #endif  /* CURL_SUPPORT_MAC_10_8 */
01200   }
01201 #else
01202   (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
01203   switch(conn->ssl_config.version) {
01204   case CURL_SSLVERSION_DEFAULT:
01205   case CURL_SSLVERSION_TLSv1:
01206   case CURL_SSLVERSION_TLSv1_0:
01207     (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01208                                        kTLSProtocol1,
01209                                        true);
01210     break;
01211   case CURL_SSLVERSION_TLSv1_1:
01212     failf(data, "Your version of the OS does not support TLSv1.1");
01213     return CURLE_SSL_CONNECT_ERROR;
01214   case CURL_SSLVERSION_TLSv1_2:
01215     failf(data, "Your version of the OS does not support TLSv1.2");
01216     return CURLE_SSL_CONNECT_ERROR;
01217   case CURL_SSLVERSION_TLSv1_3:
01218     failf(data, "Your version of the OS does not support TLSv1.3");
01219     return CURLE_SSL_CONNECT_ERROR;
01220   case CURL_SSLVERSION_SSLv2:
01221     err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01222                                        kSSLProtocol2,
01223                                        true);
01224     if(err != noErr) {
01225       failf(data, "Your version of the OS does not support SSLv2");
01226       return CURLE_SSL_CONNECT_ERROR;
01227     }
01228     break;
01229   case CURL_SSLVERSION_SSLv3:
01230     err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
01231                                        kSSLProtocol3,
01232                                        true);
01233     if(err != noErr) {
01234       failf(data, "Your version of the OS does not support SSLv3");
01235       return CURLE_SSL_CONNECT_ERROR;
01236     }
01237     break;
01238   default:
01239     failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
01240     return CURLE_SSL_CONNECT_ERROR;
01241   }
01242 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
01243 
01244   if(SSL_SET_OPTION(key)) {
01245     infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
01246           "Transport. The private key must be in the Keychain.\n");
01247   }
01248 
01249   if(ssl_cert) {
01250     SecIdentityRef cert_and_key = NULL;
01251     bool is_cert_file = is_file(ssl_cert);
01252 
01253     /* User wants to authenticate with a client cert. Look for it:
01254        If we detect that this is a file on disk, then let's load it.
01255        Otherwise, assume that the user wants to use an identity loaded
01256        from the Keychain. */
01257     if(is_cert_file) {
01258       if(!SSL_SET_OPTION(cert_type))
01259         infof(data, "WARNING: SSL: Certificate type not set, assuming "
01260                     "PKCS#12 format.\n");
01261       else if(strncmp(SSL_SET_OPTION(cert_type), "P12",
01262         strlen(SSL_SET_OPTION(cert_type))) != 0)
01263         infof(data, "WARNING: SSL: The Security framework only supports "
01264                     "loading identities that are in PKCS#12 format.\n");
01265 
01266       err = CopyIdentityFromPKCS12File(ssl_cert,
01267         SSL_SET_OPTION(key_passwd), &cert_and_key);
01268     }
01269     else
01270       err = CopyIdentityWithLabel(ssl_cert, &cert_and_key);
01271 
01272     if(err == noErr) {
01273       SecCertificateRef cert = NULL;
01274       CFTypeRef certs_c[1];
01275       CFArrayRef certs;
01276 
01277       /* If we found one, print it out: */
01278       err = SecIdentityCopyCertificate(cert_and_key, &cert);
01279       if(err == noErr) {
01280         CFStringRef cert_summary = CopyCertSubject(cert);
01281         char cert_summary_c[128];
01282 
01283         if(cert_summary) {
01284           memset(cert_summary_c, 0, 128);
01285           if(CFStringGetCString(cert_summary,
01286                                 cert_summary_c,
01287                                 128,
01288                                 kCFStringEncodingUTF8)) {
01289             infof(data, "Client certificate: %s\n", cert_summary_c);
01290           }
01291           CFRelease(cert_summary);
01292           CFRelease(cert);
01293         }
01294       }
01295       certs_c[0] = cert_and_key;
01296       certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
01297                             &kCFTypeArrayCallBacks);
01298       err = SSLSetCertificate(connssl->ssl_ctx, certs);
01299       if(certs)
01300         CFRelease(certs);
01301       if(err != noErr) {
01302         failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
01303         return CURLE_SSL_CERTPROBLEM;
01304       }
01305       CFRelease(cert_and_key);
01306     }
01307     else {
01308       switch(err) {
01309       case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
01310         failf(data, "SSL: Incorrect password for the certificate \"%s\" "
01311                     "and its private key.", ssl_cert);
01312         break;
01313       case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
01314         failf(data, "SSL: Couldn't make sense of the data in the "
01315                     "certificate \"%s\" and its private key.",
01316                     ssl_cert);
01317         break;
01318       case -25260: /* errSecPassphraseRequired */
01319         failf(data, "SSL The certificate \"%s\" requires a password.",
01320                     ssl_cert);
01321         break;
01322       case errSecItemNotFound:
01323         failf(data, "SSL: Can't find the certificate \"%s\" and its private "
01324                     "key in the Keychain.", ssl_cert);
01325         break;
01326       default:
01327         failf(data, "SSL: Can't load the certificate \"%s\" and its private "
01328                     "key: OSStatus %d", ssl_cert, err);
01329         break;
01330       }
01331       return CURLE_SSL_CERTPROBLEM;
01332     }
01333   }
01334 
01335   /* SSL always tries to verify the peer, this only says whether it should
01336    * fail to connect if the verification fails, or if it should continue
01337    * anyway. In the latter case the result of the verification is checked with
01338    * SSL_get_verify_result() below. */
01339 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
01340   /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
01341      a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
01342      works, it doesn't work as expected under Snow Leopard, Lion or
01343      Mountain Lion.
01344      So we need to call SSLSetEnableCertVerify() on those older cats in order
01345      to disable certificate validation if the user turned that off.
01346      (SecureTransport will always validate the certificate chain by
01347      default.)
01348   Note:
01349   Darwin 11.x.x is Lion (10.7)
01350   Darwin 12.x.x is Mountain Lion (10.8)
01351   Darwin 13.x.x is Mavericks (10.9)
01352   Darwin 14.x.x is Yosemite (10.10)
01353   Darwin 15.x.x is El Capitan (10.11)
01354   */
01355 #if CURL_BUILD_MAC
01356   if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
01357 #else
01358   if(SSLSetSessionOption != NULL) {
01359 #endif /* CURL_BUILD_MAC */
01360     bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
01361     err = SSLSetSessionOption(connssl->ssl_ctx,
01362                               kSSLSessionOptionBreakOnServerAuth,
01363                               break_on_auth);
01364     if(err != noErr) {
01365       failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
01366       return CURLE_SSL_CONNECT_ERROR;
01367     }
01368   }
01369   else {
01370 #if CURL_SUPPORT_MAC_10_8
01371     err = SSLSetEnableCertVerify(connssl->ssl_ctx,
01372                                  conn->ssl_config.verifypeer?true:false);
01373     if(err != noErr) {
01374       failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
01375       return CURLE_SSL_CONNECT_ERROR;
01376     }
01377 #endif /* CURL_SUPPORT_MAC_10_8 */
01378   }
01379 #else
01380   err = SSLSetEnableCertVerify(connssl->ssl_ctx,
01381                                conn->ssl_config.verifypeer?true:false);
01382   if(err != noErr) {
01383     failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
01384     return CURLE_SSL_CONNECT_ERROR;
01385   }
01386 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
01387 
01388   if(ssl_cafile) {
01389     bool is_cert_file = is_file(ssl_cafile);
01390 
01391     if(!is_cert_file) {
01392       failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
01393       return CURLE_SSL_CACERT_BADFILE;
01394     }
01395     if(!verifypeer) {
01396       failf(data, "SSL: CA certificate set, but certificate verification "
01397             "is disabled");
01398       return CURLE_SSL_CONNECT_ERROR;
01399     }
01400   }
01401 
01402   /* Configure hostname check. SNI is used if available.
01403    * Both hostname check and SNI require SSLSetPeerDomainName().
01404    * Also: the verifyhost setting influences SNI usage */
01405   if(conn->ssl_config.verifyhost) {
01406     err = SSLSetPeerDomainName(connssl->ssl_ctx, hostname,
01407     strlen(hostname));
01408 
01409     if(err != noErr) {
01410       infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
01411             err);
01412     }
01413 
01414     if((Curl_inet_pton(AF_INET, hostname, &addr))
01415   #ifdef ENABLE_IPV6
01416     || (Curl_inet_pton(AF_INET6, hostname, &addr))
01417   #endif
01418        ) {
01419       infof(data, "WARNING: using IP address, SNI is being disabled by "
01420             "the OS.\n");
01421     }
01422   }
01423 
01424   /* Disable cipher suites that ST supports but are not safe. These ciphers
01425      are unlikely to be used in any case since ST gives other ciphers a much
01426      higher priority, but it's probably better that we not connect at all than
01427      to give the user a false sense of security if the server only supports
01428      insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
01429   (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
01430   all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
01431   allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
01432   if(all_ciphers && allowed_ciphers &&
01433      SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
01434        &all_ciphers_count) == noErr) {
01435     for(i = 0UL ; i < all_ciphers_count ; i++) {
01436 #if CURL_BUILD_MAC
01437      /* There's a known bug in early versions of Mountain Lion where ST's ECC
01438         ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
01439         Work around the problem here by disabling those ciphers if we are
01440         running in an affected version of OS X. */
01441       if(darwinver_maj == 12 && darwinver_min <= 3 &&
01442          all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
01443         continue;
01444       }
01445 #endif /* CURL_BUILD_MAC */
01446       switch(all_ciphers[i]) {
01447         /* Disable NULL ciphersuites: */
01448         case SSL_NULL_WITH_NULL_NULL:
01449         case SSL_RSA_WITH_NULL_MD5:
01450         case SSL_RSA_WITH_NULL_SHA:
01451         case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
01452         case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
01453         case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
01454         case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
01455         case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
01456         case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
01457         case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
01458         case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
01459         case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
01460         case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
01461         case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
01462         case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
01463         case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
01464         case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
01465         case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
01466         /* Disable anonymous ciphersuites: */
01467         case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
01468         case SSL_DH_anon_WITH_RC4_128_MD5:
01469         case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
01470         case SSL_DH_anon_WITH_DES_CBC_SHA:
01471         case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
01472         case TLS_DH_anon_WITH_AES_128_CBC_SHA:
01473         case TLS_DH_anon_WITH_AES_256_CBC_SHA:
01474         case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
01475         case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
01476         case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
01477         case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
01478         case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
01479         case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
01480         case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
01481         case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
01482         case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
01483         /* Disable weak key ciphersuites: */
01484         case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
01485         case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
01486         case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
01487         case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
01488         case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
01489         case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
01490         case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
01491         case SSL_RSA_WITH_DES_CBC_SHA:
01492         case SSL_DH_DSS_WITH_DES_CBC_SHA:
01493         case SSL_DH_RSA_WITH_DES_CBC_SHA:
01494         case SSL_DHE_DSS_WITH_DES_CBC_SHA:
01495         case SSL_DHE_RSA_WITH_DES_CBC_SHA:
01496         /* Disable IDEA: */
01497         case SSL_RSA_WITH_IDEA_CBC_SHA:
01498         case SSL_RSA_WITH_IDEA_CBC_MD5:
01499         /* Disable RC4: */
01500         case SSL_RSA_WITH_RC4_128_MD5:
01501         case SSL_RSA_WITH_RC4_128_SHA:
01502         case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
01503         case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/
01504         case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
01505         case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
01506         case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */
01507         case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */
01508         case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */
01509           break;
01510         default: /* enable everything else */
01511           allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
01512           break;
01513       }
01514     }
01515     err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
01516                                allowed_ciphers_count);
01517     if(err != noErr) {
01518       failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
01519       return CURLE_SSL_CONNECT_ERROR;
01520     }
01521   }
01522   else {
01523     Curl_safefree(all_ciphers);
01524     Curl_safefree(allowed_ciphers);
01525     failf(data, "SSL: Failed to allocate memory for allowed ciphers");
01526     return CURLE_OUT_OF_MEMORY;
01527   }
01528   Curl_safefree(all_ciphers);
01529   Curl_safefree(allowed_ciphers);
01530 
01531 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
01532   /* We want to enable 1/n-1 when using a CBC cipher unless the user
01533      specifically doesn't want us doing that: */
01534   if(SSLSetSessionOption != NULL) {
01535     /* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */
01536     SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
01537                       !data->set.ssl.enable_beast);
01538     SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
01539                       data->set.ssl.falsestart); /* false start support */
01540   }
01541 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
01542 
01543   /* Check if there's a cached ID we can/should use here! */
01544   if(data->set.general_ssl.sessionid) {
01545     char *ssl_sessionid;
01546     size_t ssl_sessionid_len;
01547 
01548     Curl_ssl_sessionid_lock(conn);
01549     if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
01550                               &ssl_sessionid_len, sockindex)) {
01551       /* we got a session id, use it! */
01552       err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
01553       Curl_ssl_sessionid_unlock(conn);
01554       if(err != noErr) {
01555         failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
01556         return CURLE_SSL_CONNECT_ERROR;
01557       }
01558       /* Informational message */
01559       infof(data, "SSL re-using session ID\n");
01560     }
01561     /* If there isn't one, then let's make one up! This has to be done prior
01562        to starting the handshake. */
01563     else {
01564       CURLcode result;
01565       ssl_sessionid =
01566         aprintf("%s:%d:%d:%s:%hu", ssl_cafile,
01567                 verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
01568       ssl_sessionid_len = strlen(ssl_sessionid);
01569 
01570       err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
01571       if(err != noErr) {
01572         Curl_ssl_sessionid_unlock(conn);
01573         failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
01574         return CURLE_SSL_CONNECT_ERROR;
01575       }
01576 
01577       result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len,
01578                                      sockindex);
01579       Curl_ssl_sessionid_unlock(conn);
01580       if(result) {
01581         failf(data, "failed to store ssl session");
01582         return result;
01583       }
01584     }
01585   }
01586 
01587   err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
01588   if(err != noErr) {
01589     failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
01590     return CURLE_SSL_CONNECT_ERROR;
01591   }
01592 
01593   /* pass the raw socket into the SSL layers */
01594   /* We need to store the FD in a constant memory address, because
01595    * SSLSetConnection() will not copy that address. I've found that
01596    * conn->sock[sockindex] may change on its own. */
01597   connssl->ssl_sockfd = sockfd;
01598   err = SSLSetConnection(connssl->ssl_ctx, connssl);
01599   if(err != noErr) {
01600     failf(data, "SSL: SSLSetConnection() failed: %d", err);
01601     return CURLE_SSL_CONNECT_ERROR;
01602   }
01603 
01604   connssl->connecting_state = ssl_connect_2;
01605   return CURLE_OK;
01606 }
01607 
01608 static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
01609 {
01610   char *sep_start, *sep_end, *cert_start, *cert_end;
01611   size_t i, j, err;
01612   size_t len;
01613   unsigned char *b64;
01614 
01615   /* Jump through the separators at the beginning of the certificate. */
01616   sep_start = strstr(in, "-----");
01617   if(sep_start == NULL)
01618     return 0;
01619   cert_start = strstr(sep_start + 1, "-----");
01620   if(cert_start == NULL)
01621     return -1;
01622 
01623   cert_start += 5;
01624 
01625   /* Find separator after the end of the certificate. */
01626   cert_end = strstr(cert_start, "-----");
01627   if(cert_end == NULL)
01628     return -1;
01629 
01630   sep_end = strstr(cert_end + 1, "-----");
01631   if(sep_end == NULL)
01632     return -1;
01633   sep_end += 5;
01634 
01635   len = cert_end - cert_start;
01636   b64 = malloc(len + 1);
01637   if(!b64)
01638     return -1;
01639 
01640   /* Create base64 string without linefeeds. */
01641   for(i = 0, j = 0; i < len; i++) {
01642     if(cert_start[i] != '\r' && cert_start[i] != '\n')
01643       b64[j++] = cert_start[i];
01644   }
01645   b64[j] = '\0';
01646 
01647   err = Curl_base64_decode((const char *)b64, out, outlen);
01648   free(b64);
01649   if(err) {
01650     free(*out);
01651     return -1;
01652   }
01653 
01654   return sep_end - in;
01655 }
01656 
01657 static int read_cert(const char *file, unsigned char **out, size_t *outlen)
01658 {
01659   int fd;
01660   ssize_t n, len = 0, cap = 512;
01661   unsigned char buf[cap], *data;
01662 
01663   fd = open(file, 0);
01664   if(fd < 0)
01665     return -1;
01666 
01667   data = malloc(cap);
01668   if(!data) {
01669     close(fd);
01670     return -1;
01671   }
01672 
01673   for(;;) {
01674     n = read(fd, buf, sizeof(buf));
01675     if(n < 0) {
01676       close(fd);
01677       free(data);
01678       return -1;
01679     }
01680     else if(n == 0) {
01681       close(fd);
01682       break;
01683     }
01684 
01685     if(len + n >= cap) {
01686       cap *= 2;
01687       data = realloc(data, cap);
01688       if(!data) {
01689         close(fd);
01690         return -1;
01691       }
01692     }
01693 
01694     memcpy(data + len, buf, n);
01695     len += n;
01696   }
01697   data[len] = '\0';
01698 
01699   *out = data;
01700   *outlen = len;
01701 
01702   return 0;
01703 }
01704 
01705 static int sslerr_to_curlerr(struct Curl_easy *data, int err)
01706 {
01707   switch(err) {
01708     case errSSLXCertChainInvalid:
01709       failf(data, "SSL certificate problem: Invalid certificate chain");
01710       return CURLE_SSL_CACERT;
01711     case errSSLUnknownRootCert:
01712       failf(data, "SSL certificate problem: Untrusted root certificate");
01713       return CURLE_SSL_CACERT;
01714     case errSSLNoRootCert:
01715       failf(data, "SSL certificate problem: No root certificate");
01716       return CURLE_SSL_CACERT;
01717     case errSSLCertExpired:
01718       failf(data, "SSL certificate problem: Certificate chain had an "
01719             "expired certificate");
01720       return CURLE_SSL_CACERT;
01721     case errSSLBadCert:
01722       failf(data, "SSL certificate problem: Couldn't understand the server "
01723             "certificate format");
01724       return CURLE_SSL_CONNECT_ERROR;
01725     case errSSLHostNameMismatch:
01726       failf(data, "SSL certificate peer hostname mismatch");
01727       return CURLE_PEER_FAILED_VERIFICATION;
01728     default:
01729       failf(data, "SSL unexpected certificate error %d", err);
01730       return CURLE_SSL_CACERT;
01731   }
01732 }
01733 
01734 static int append_cert_to_array(struct Curl_easy *data,
01735                                 unsigned char *buf, size_t buflen,
01736                                 CFMutableArrayRef array)
01737 {
01738     CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
01739     if(!certdata) {
01740       failf(data, "SSL: failed to allocate array for CA certificate");
01741       return CURLE_OUT_OF_MEMORY;
01742     }
01743 
01744     SecCertificateRef cacert =
01745       SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
01746     CFRelease(certdata);
01747     if(!cacert) {
01748       failf(data, "SSL: failed to create SecCertificate from CA certificate");
01749       return CURLE_SSL_CACERT;
01750     }
01751 
01752     /* Check if cacert is valid. */
01753     CFStringRef subject = CopyCertSubject(cacert);
01754     if(subject) {
01755       char subject_cbuf[128];
01756       memset(subject_cbuf, 0, 128);
01757       if(!CFStringGetCString(subject,
01758                             subject_cbuf,
01759                             128,
01760                             kCFStringEncodingUTF8)) {
01761         CFRelease(cacert);
01762         failf(data, "SSL: invalid CA certificate subject");
01763         return CURLE_SSL_CACERT;
01764       }
01765       CFRelease(subject);
01766     }
01767     else {
01768       CFRelease(cacert);
01769       failf(data, "SSL: invalid CA certificate");
01770       return CURLE_SSL_CACERT;
01771     }
01772 
01773     CFArrayAppendValue(array, cacert);
01774     CFRelease(cacert);
01775 
01776     return CURLE_OK;
01777 }
01778 
01779 static int verify_cert(const char *cafile, struct Curl_easy *data,
01780                        SSLContextRef ctx)
01781 {
01782   int n = 0, rc;
01783   long res;
01784   unsigned char *certbuf, *der;
01785   size_t buflen, derlen, offset = 0;
01786 
01787   if(read_cert(cafile, &certbuf, &buflen) < 0) {
01788     failf(data, "SSL: failed to read or invalid CA certificate");
01789     return CURLE_SSL_CACERT;
01790   }
01791 
01792   /*
01793    * Certbuf now contains the contents of the certificate file, which can be
01794    * - a single DER certificate,
01795    * - a single PEM certificate or
01796    * - a bunch of PEM certificates (certificate bundle).
01797    *
01798    * Go through certbuf, and convert any PEM certificate in it into DER
01799    * format.
01800    */
01801   CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
01802                                                  &kCFTypeArrayCallBacks);
01803   if(array == NULL) {
01804     free(certbuf);
01805     failf(data, "SSL: out of memory creating CA certificate array");
01806     return CURLE_OUT_OF_MEMORY;
01807   }
01808 
01809   while(offset < buflen) {
01810     n++;
01811 
01812     /*
01813      * Check if the certificate is in PEM format, and convert it to DER. If
01814      * this fails, we assume the certificate is in DER format.
01815      */
01816     res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
01817     if(res < 0) {
01818       free(certbuf);
01819       CFRelease(array);
01820       failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
01821             n, offset);
01822       return CURLE_SSL_CACERT;
01823     }
01824     offset += res;
01825 
01826     if(res == 0 && offset == 0) {
01827       /* This is not a PEM file, probably a certificate in DER format. */
01828       rc = append_cert_to_array(data, certbuf, buflen, array);
01829       free(certbuf);
01830       if(rc != CURLE_OK) {
01831         CFRelease(array);
01832         return rc;
01833       }
01834       break;
01835     }
01836     else if(res == 0) {
01837       /* No more certificates in the bundle. */
01838       free(certbuf);
01839       break;
01840     }
01841 
01842     rc = append_cert_to_array(data, der, derlen, array);
01843     free(der);
01844     if(rc != CURLE_OK) {
01845       free(certbuf);
01846       CFRelease(array);
01847       return rc;
01848     }
01849   }
01850 
01851   SecTrustRef trust;
01852   OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
01853   if(trust == NULL) {
01854     failf(data, "SSL: error getting certificate chain");
01855     CFRelease(array);
01856     return CURLE_OUT_OF_MEMORY;
01857   }
01858   else if(ret != noErr) {
01859     CFRelease(array);
01860     return sslerr_to_curlerr(data, ret);
01861   }
01862 
01863   ret = SecTrustSetAnchorCertificates(trust, array);
01864   if(ret != noErr) {
01865     CFRelease(trust);
01866     return sslerr_to_curlerr(data, ret);
01867   }
01868   ret = SecTrustSetAnchorCertificatesOnly(trust, true);
01869   if(ret != noErr) {
01870     CFRelease(trust);
01871     return sslerr_to_curlerr(data, ret);
01872   }
01873 
01874   SecTrustResultType trust_eval = 0;
01875   ret = SecTrustEvaluate(trust, &trust_eval);
01876   CFRelease(array);
01877   CFRelease(trust);
01878   if(ret != noErr) {
01879     return sslerr_to_curlerr(data, ret);
01880   }
01881 
01882   switch(trust_eval) {
01883     case kSecTrustResultUnspecified:
01884     case kSecTrustResultProceed:
01885       return CURLE_OK;
01886 
01887     case kSecTrustResultRecoverableTrustFailure:
01888     case kSecTrustResultDeny:
01889     default:
01890       failf(data, "SSL: certificate verification failed (result: %d)",
01891             trust_eval);
01892       return CURLE_PEER_FAILED_VERIFICATION;
01893   }
01894 }
01895 
01896 static CURLcode
01897 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
01898 {
01899   struct Curl_easy *data = conn->data;
01900   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
01901   OSStatus err;
01902   SSLCipherSuite cipher;
01903   SSLProtocol protocol = 0;
01904   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
01905     conn->host.name;
01906 
01907   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
01908               || ssl_connect_2_reading == connssl->connecting_state
01909               || ssl_connect_2_writing == connssl->connecting_state);
01910 
01911   /* Here goes nothing: */
01912   err = SSLHandshake(connssl->ssl_ctx);
01913 
01914   if(err != noErr) {
01915     switch(err) {
01916       case errSSLWouldBlock:  /* they're not done with us yet */
01917         connssl->connecting_state = connssl->ssl_direction ?
01918             ssl_connect_2_writing : ssl_connect_2_reading;
01919         return CURLE_OK;
01920 
01921       /* The below is errSSLServerAuthCompleted; it's not defined in
01922         Leopard's headers */
01923       case -9841:
01924         if(SSL_CONN_CONFIG(CAfile)) {
01925           int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
01926                                 connssl->ssl_ctx);
01927           if(res != CURLE_OK)
01928             return res;
01929         }
01930         /* the documentation says we need to call SSLHandshake() again */
01931         return darwinssl_connect_step2(conn, sockindex);
01932 
01933       /* These are all certificate problems with the server: */
01934       case errSSLXCertChainInvalid:
01935         failf(data, "SSL certificate problem: Invalid certificate chain");
01936         return CURLE_SSL_CACERT;
01937       case errSSLUnknownRootCert:
01938         failf(data, "SSL certificate problem: Untrusted root certificate");
01939         return CURLE_SSL_CACERT;
01940       case errSSLNoRootCert:
01941         failf(data, "SSL certificate problem: No root certificate");
01942         return CURLE_SSL_CACERT;
01943       case errSSLCertExpired:
01944         failf(data, "SSL certificate problem: Certificate chain had an "
01945               "expired certificate");
01946         return CURLE_SSL_CACERT;
01947       case errSSLBadCert:
01948         failf(data, "SSL certificate problem: Couldn't understand the server "
01949               "certificate format");
01950         return CURLE_SSL_CONNECT_ERROR;
01951 
01952       /* These are all certificate problems with the client: */
01953       case errSecAuthFailed:
01954         failf(data, "SSL authentication failed");
01955         return CURLE_SSL_CONNECT_ERROR;
01956       case errSSLPeerHandshakeFail:
01957         failf(data, "SSL peer handshake failed, the server most likely "
01958               "requires a client certificate to connect");
01959         return CURLE_SSL_CONNECT_ERROR;
01960       case errSSLPeerUnknownCA:
01961         failf(data, "SSL server rejected the client certificate due to "
01962               "the certificate being signed by an unknown certificate "
01963               "authority");
01964         return CURLE_SSL_CONNECT_ERROR;
01965 
01966       /* This error is raised if the server's cert didn't match the server's
01967          host name: */
01968       case errSSLHostNameMismatch:
01969         failf(data, "SSL certificate peer verification failed, the "
01970               "certificate did not match \"%s\"\n", conn->host.dispname);
01971         return CURLE_PEER_FAILED_VERIFICATION;
01972 
01973       /* Generic handshake errors: */
01974       case errSSLConnectionRefused:
01975         failf(data, "Server dropped the connection during the SSL handshake");
01976         return CURLE_SSL_CONNECT_ERROR;
01977       case errSSLClosedAbort:
01978         failf(data, "Server aborted the SSL handshake");
01979         return CURLE_SSL_CONNECT_ERROR;
01980       case errSSLNegotiation:
01981         failf(data, "Could not negotiate an SSL cipher suite with the server");
01982         return CURLE_SSL_CONNECT_ERROR;
01983       /* Sometimes paramErr happens with buggy ciphers: */
01984       case paramErr: case errSSLInternal:
01985         failf(data, "Internal SSL engine error encountered during the "
01986               "SSL handshake");
01987         return CURLE_SSL_CONNECT_ERROR;
01988       case errSSLFatalAlert:
01989         failf(data, "Fatal SSL engine error encountered during the SSL "
01990               "handshake");
01991         return CURLE_SSL_CONNECT_ERROR;
01992       default:
01993         failf(data, "Unknown SSL protocol error in connection to %s:%d",
01994               hostname, err);
01995         return CURLE_SSL_CONNECT_ERROR;
01996     }
01997   }
01998   else {
01999     /* we have been connected fine, we're not waiting for anything else. */
02000     connssl->connecting_state = ssl_connect_3;
02001 
02002     /* Informational message */
02003     (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
02004     (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
02005     switch(protocol) {
02006       case kSSLProtocol2:
02007         infof(data, "SSL 2.0 connection using %s\n",
02008               SSLCipherNameForNumber(cipher));
02009         break;
02010       case kSSLProtocol3:
02011         infof(data, "SSL 3.0 connection using %s\n",
02012               SSLCipherNameForNumber(cipher));
02013         break;
02014       case kTLSProtocol1:
02015         infof(data, "TLS 1.0 connection using %s\n",
02016               TLSCipherNameForNumber(cipher));
02017         break;
02018 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
02019       case kTLSProtocol11:
02020         infof(data, "TLS 1.1 connection using %s\n",
02021               TLSCipherNameForNumber(cipher));
02022         break;
02023       case kTLSProtocol12:
02024         infof(data, "TLS 1.2 connection using %s\n",
02025               TLSCipherNameForNumber(cipher));
02026         break;
02027 #endif
02028       default:
02029         infof(data, "Unknown protocol connection\n");
02030         break;
02031     }
02032 
02033     return CURLE_OK;
02034   }
02035 }
02036 
02037 static CURLcode
02038 darwinssl_connect_step3(struct connectdata *conn,
02039                         int sockindex)
02040 {
02041   struct Curl_easy *data = conn->data;
02042   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
02043   CFStringRef server_cert_summary;
02044   char server_cert_summary_c[128];
02045   CFArrayRef server_certs = NULL;
02046   SecCertificateRef server_cert;
02047   OSStatus err;
02048   CFIndex i, count;
02049   SecTrustRef trust = NULL;
02050 
02051   /* There is no step 3!
02052    * Well, okay, if verbose mode is on, let's print the details of the
02053    * server certificates. */
02054 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
02055 #if CURL_BUILD_IOS
02056 #pragma unused(server_certs)
02057   err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
02058   /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
02059      a null trust, so be on guard for that: */
02060   if(err == noErr && trust) {
02061     count = SecTrustGetCertificateCount(trust);
02062     for(i = 0L ; i < count ; i++) {
02063       server_cert = SecTrustGetCertificateAtIndex(trust, i);
02064       server_cert_summary = CopyCertSubject(server_cert);
02065       memset(server_cert_summary_c, 0, 128);
02066       if(CFStringGetCString(server_cert_summary,
02067                             server_cert_summary_c,
02068                             128,
02069                             kCFStringEncodingUTF8)) {
02070         infof(data, "Server certificate: %s\n", server_cert_summary_c);
02071       }
02072       CFRelease(server_cert_summary);
02073     }
02074     CFRelease(trust);
02075   }
02076 #else
02077   /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
02078      The function SecTrustGetCertificateAtIndex() is officially present
02079      in Lion, but it is unfortunately also present in Snow Leopard as
02080      private API and doesn't work as expected. So we have to look for
02081      a different symbol to make sure this code is only executed under
02082      Lion or later. */
02083   if(SecTrustEvaluateAsync != NULL) {
02084 #pragma unused(server_certs)
02085     err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
02086     /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
02087        a null trust, so be on guard for that: */
02088     if(err == noErr && trust) {
02089       count = SecTrustGetCertificateCount(trust);
02090       for(i = 0L ; i < count ; i++) {
02091         server_cert = SecTrustGetCertificateAtIndex(trust, i);
02092         server_cert_summary = CopyCertSubject(server_cert);
02093         memset(server_cert_summary_c, 0, 128);
02094         if(CFStringGetCString(server_cert_summary,
02095                               server_cert_summary_c,
02096                               128,
02097                               kCFStringEncodingUTF8)) {
02098           infof(data, "Server certificate: %s\n", server_cert_summary_c);
02099         }
02100         CFRelease(server_cert_summary);
02101       }
02102       CFRelease(trust);
02103     }
02104   }
02105   else {
02106 #if CURL_SUPPORT_MAC_10_8
02107     err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
02108     /* Just in case SSLCopyPeerCertificates() returns null too... */
02109     if(err == noErr && server_certs) {
02110       count = CFArrayGetCount(server_certs);
02111       for(i = 0L ; i < count ; i++) {
02112         server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
02113                                                                 i);
02114 
02115         server_cert_summary = CopyCertSubject(server_cert);
02116         memset(server_cert_summary_c, 0, 128);
02117         if(CFStringGetCString(server_cert_summary,
02118                               server_cert_summary_c,
02119                               128,
02120                               kCFStringEncodingUTF8)) {
02121           infof(data, "Server certificate: %s\n", server_cert_summary_c);
02122         }
02123         CFRelease(server_cert_summary);
02124       }
02125       CFRelease(server_certs);
02126     }
02127 #endif /* CURL_SUPPORT_MAC_10_8 */
02128   }
02129 #endif /* CURL_BUILD_IOS */
02130 #else
02131 #pragma unused(trust)
02132   err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
02133   if(err == noErr) {
02134     count = CFArrayGetCount(server_certs);
02135     for(i = 0L ; i < count ; i++) {
02136       server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
02137       server_cert_summary = CopyCertSubject(server_cert);
02138       memset(server_cert_summary_c, 0, 128);
02139       if(CFStringGetCString(server_cert_summary,
02140                             server_cert_summary_c,
02141                             128,
02142                             kCFStringEncodingUTF8)) {
02143         infof(data, "Server certificate: %s\n", server_cert_summary_c);
02144       }
02145       CFRelease(server_cert_summary);
02146     }
02147     CFRelease(server_certs);
02148   }
02149 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
02150 
02151   connssl->connecting_state = ssl_connect_done;
02152   return CURLE_OK;
02153 }
02154 
02155 static Curl_recv darwinssl_recv;
02156 static Curl_send darwinssl_send;
02157 
02158 static CURLcode
02159 darwinssl_connect_common(struct connectdata *conn,
02160                          int sockindex,
02161                          bool nonblocking,
02162                          bool *done)
02163 {
02164   CURLcode result;
02165   struct Curl_easy *data = conn->data;
02166   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
02167   curl_socket_t sockfd = conn->sock[sockindex];
02168   long timeout_ms;
02169   int what;
02170 
02171   /* check if the connection has already been established */
02172   if(ssl_connection_complete == connssl->state) {
02173     *done = TRUE;
02174     return CURLE_OK;
02175   }
02176 
02177   if(ssl_connect_1==connssl->connecting_state) {
02178     /* Find out how much more time we're allowed */
02179     timeout_ms = Curl_timeleft(data, NULL, TRUE);
02180 
02181     if(timeout_ms < 0) {
02182       /* no need to continue if time already is up */
02183       failf(data, "SSL connection timeout");
02184       return CURLE_OPERATION_TIMEDOUT;
02185     }
02186 
02187     result = darwinssl_connect_step1(conn, sockindex);
02188     if(result)
02189       return result;
02190   }
02191 
02192   while(ssl_connect_2 == connssl->connecting_state ||
02193         ssl_connect_2_reading == connssl->connecting_state ||
02194         ssl_connect_2_writing == connssl->connecting_state) {
02195 
02196     /* check allowed time left */
02197     timeout_ms = Curl_timeleft(data, NULL, TRUE);
02198 
02199     if(timeout_ms < 0) {
02200       /* no need to continue if time already is up */
02201       failf(data, "SSL connection timeout");
02202       return CURLE_OPERATION_TIMEDOUT;
02203     }
02204 
02205     /* if ssl is expecting something, check if it's available. */
02206     if(connssl->connecting_state == ssl_connect_2_reading ||
02207        connssl->connecting_state == ssl_connect_2_writing) {
02208 
02209       curl_socket_t writefd = ssl_connect_2_writing ==
02210       connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
02211       curl_socket_t readfd = ssl_connect_2_reading ==
02212       connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
02213 
02214       what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
02215                                nonblocking?0:timeout_ms);
02216       if(what < 0) {
02217         /* fatal error */
02218         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
02219         return CURLE_SSL_CONNECT_ERROR;
02220       }
02221       else if(0 == what) {
02222         if(nonblocking) {
02223           *done = FALSE;
02224           return CURLE_OK;
02225         }
02226         else {
02227           /* timeout */
02228           failf(data, "SSL connection timeout");
02229           return CURLE_OPERATION_TIMEDOUT;
02230         }
02231       }
02232       /* socket is readable or writable */
02233     }
02234 
02235     /* Run transaction, and return to the caller if it failed or if this
02236      * connection is done nonblocking and this loop would execute again. This
02237      * permits the owner of a multi handle to abort a connection attempt
02238      * before step2 has completed while ensuring that a client using select()
02239      * or epoll() will always have a valid fdset to wait on.
02240      */
02241     result = darwinssl_connect_step2(conn, sockindex);
02242     if(result || (nonblocking &&
02243                   (ssl_connect_2 == connssl->connecting_state ||
02244                    ssl_connect_2_reading == connssl->connecting_state ||
02245                    ssl_connect_2_writing == connssl->connecting_state)))
02246       return result;
02247 
02248   } /* repeat step2 until all transactions are done. */
02249 
02250 
02251   if(ssl_connect_3 == connssl->connecting_state) {
02252     result = darwinssl_connect_step3(conn, sockindex);
02253     if(result)
02254       return result;
02255   }
02256 
02257   if(ssl_connect_done == connssl->connecting_state) {
02258     connssl->state = ssl_connection_complete;
02259     conn->recv[sockindex] = darwinssl_recv;
02260     conn->send[sockindex] = darwinssl_send;
02261     *done = TRUE;
02262   }
02263   else
02264     *done = FALSE;
02265 
02266   /* Reset our connect state machine */
02267   connssl->connecting_state = ssl_connect_1;
02268 
02269   return CURLE_OK;
02270 }
02271 
02272 CURLcode
02273 Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
02274                                    int sockindex,
02275                                    bool *done)
02276 {
02277   return darwinssl_connect_common(conn, sockindex, TRUE, done);
02278 }
02279 
02280 CURLcode
02281 Curl_darwinssl_connect(struct connectdata *conn,
02282                        int sockindex)
02283 {
02284   CURLcode result;
02285   bool done = FALSE;
02286 
02287   result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
02288 
02289   if(result)
02290     return result;
02291 
02292   DEBUGASSERT(done);
02293 
02294   return CURLE_OK;
02295 }
02296 
02297 void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
02298 {
02299   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
02300 
02301   if(connssl->ssl_ctx) {
02302     (void)SSLClose(connssl->ssl_ctx);
02303 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
02304     if(SSLCreateContext != NULL)
02305       CFRelease(connssl->ssl_ctx);
02306 #if CURL_SUPPORT_MAC_10_8
02307     else
02308       (void)SSLDisposeContext(connssl->ssl_ctx);
02309 #endif  /* CURL_SUPPORT_MAC_10_8 */
02310 #else
02311     (void)SSLDisposeContext(connssl->ssl_ctx);
02312 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
02313     connssl->ssl_ctx = NULL;
02314   }
02315   connssl->ssl_sockfd = 0;
02316 }
02317 
02318 int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
02319 {
02320   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
02321   struct Curl_easy *data = conn->data;
02322   ssize_t nread;
02323   int what;
02324   int rc;
02325   char buf[120];
02326 
02327   if(!connssl->ssl_ctx)
02328     return 0;
02329 
02330   if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
02331     return 0;
02332 
02333   Curl_darwinssl_close(conn, sockindex);
02334 
02335   rc = 0;
02336 
02337   what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
02338 
02339   for(;;) {
02340     if(what < 0) {
02341       /* anything that gets here is fatally bad */
02342       failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
02343       rc = -1;
02344       break;
02345     }
02346 
02347     if(!what) {                                /* timeout */
02348       failf(data, "SSL shutdown timeout");
02349       break;
02350     }
02351 
02352     /* Something to read, let's do it and hope that it is the close
02353      notify alert from the server. No way to SSL_Read now, so use read(). */
02354 
02355     nread = read(conn->sock[sockindex], buf, sizeof(buf));
02356 
02357     if(nread < 0) {
02358       failf(data, "read: %s", strerror(errno));
02359       rc = -1;
02360     }
02361 
02362     if(nread <= 0)
02363       break;
02364 
02365     what = SOCKET_READABLE(conn->sock[sockindex], 0);
02366   }
02367 
02368   return rc;
02369 }
02370 
02371 void Curl_darwinssl_session_free(void *ptr)
02372 {
02373   /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
02374      cached session ID inside the Security framework. There is a private
02375      function that does this, but I don't want to have to explain to you why I
02376      got your application rejected from the App Store due to the use of a
02377      private API, so the best we can do is free up our own char array that we
02378      created way back in darwinssl_connect_step1... */
02379   Curl_safefree(ptr);
02380 }
02381 
02382 size_t Curl_darwinssl_version(char *buffer, size_t size)
02383 {
02384   return snprintf(buffer, size, "SecureTransport");
02385 }
02386 
02387 /*
02388  * This function uses SSLGetSessionState to determine connection status.
02389  *
02390  * Return codes:
02391  *     1 means the connection is still in place
02392  *     0 means the connection has been closed
02393  *    -1 means the connection status is unknown
02394  */
02395 int Curl_darwinssl_check_cxn(struct connectdata *conn)
02396 {
02397   struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
02398   OSStatus err;
02399   SSLSessionState state;
02400 
02401   if(connssl->ssl_ctx) {
02402     err = SSLGetSessionState(connssl->ssl_ctx, &state);
02403     if(err == noErr)
02404       return state == kSSLConnected || state == kSSLHandshake;
02405     return -1;
02406   }
02407   return 0;
02408 }
02409 
02410 bool Curl_darwinssl_data_pending(const struct connectdata *conn,
02411                                  int connindex)
02412 {
02413   const struct ssl_connect_data *connssl = &conn->ssl[connindex];
02414   OSStatus err;
02415   size_t buffer;
02416 
02417   if(connssl->ssl_ctx) {  /* SSL is in use */
02418     err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
02419     if(err == noErr)
02420       return buffer > 0UL;
02421     return false;
02422   }
02423   else
02424     return false;
02425 }
02426 
02427 int Curl_darwinssl_random(unsigned char *entropy,
02428                           size_t length)
02429 {
02430   /* arc4random_buf() isn't available on cats older than Lion, so let's
02431      do this manually for the benefit of the older cats. */
02432   size_t i;
02433   u_int32_t random_number = 0;
02434 
02435   for(i = 0 ; i < length ; i++) {
02436     if(i % sizeof(u_int32_t) == 0)
02437       random_number = arc4random();
02438     entropy[i] = random_number & 0xFF;
02439     random_number >>= 8;
02440   }
02441   i = random_number = 0;
02442   return 0;
02443 }
02444 
02445 void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
02446                            size_t tmplen,
02447                            unsigned char *md5sum, /* output */
02448                            size_t md5len)
02449 {
02450   (void)md5len;
02451   (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
02452 }
02453 
02454 bool Curl_darwinssl_false_start(void)
02455 {
02456 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
02457   if(SSLSetSessionOption != NULL)
02458     return TRUE;
02459 #endif
02460   return FALSE;
02461 }
02462 
02463 static ssize_t darwinssl_send(struct connectdata *conn,
02464                               int sockindex,
02465                               const void *mem,
02466                               size_t len,
02467                               CURLcode *curlcode)
02468 {
02469   /*struct Curl_easy *data = conn->data;*/
02470   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
02471   size_t processed = 0UL;
02472   OSStatus err;
02473 
02474   /* The SSLWrite() function works a little differently than expected. The
02475      fourth argument (processed) is currently documented in Apple's
02476      documentation as: "On return, the length, in bytes, of the data actually
02477      written."
02478 
02479      Now, one could interpret that as "written to the socket," but actually,
02480      it returns the amount of data that was written to a buffer internal to
02481      the SSLContextRef instead. So it's possible for SSLWrite() to return
02482      errSSLWouldBlock and a number of bytes "written" because those bytes were
02483      encrypted and written to a buffer, not to the socket.
02484 
02485      So if this happens, then we need to keep calling SSLWrite() over and
02486      over again with no new data until it quits returning errSSLWouldBlock. */
02487 
02488   /* Do we have buffered data to write from the last time we were called? */
02489   if(connssl->ssl_write_buffered_length) {
02490     /* Write the buffered data: */
02491     err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
02492     switch(err) {
02493       case noErr:
02494         /* processed is always going to be 0 because we didn't write to
02495            the buffer, so return how much was written to the socket */
02496         processed = connssl->ssl_write_buffered_length;
02497         connssl->ssl_write_buffered_length = 0UL;
02498         break;
02499       case errSSLWouldBlock: /* argh, try again */
02500         *curlcode = CURLE_AGAIN;
02501         return -1L;
02502       default:
02503         failf(conn->data, "SSLWrite() returned error %d", err);
02504         *curlcode = CURLE_SEND_ERROR;
02505         return -1L;
02506     }
02507   }
02508   else {
02509     /* We've got new data to write: */
02510     err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
02511     if(err != noErr) {
02512       switch(err) {
02513         case errSSLWouldBlock:
02514           /* Data was buffered but not sent, we have to tell the caller
02515              to try sending again, and remember how much was buffered */
02516           connssl->ssl_write_buffered_length = len;
02517           *curlcode = CURLE_AGAIN;
02518           return -1L;
02519         default:
02520           failf(conn->data, "SSLWrite() returned error %d", err);
02521           *curlcode = CURLE_SEND_ERROR;
02522           return -1L;
02523       }
02524     }
02525   }
02526   return (ssize_t)processed;
02527 }
02528 
02529 static ssize_t darwinssl_recv(struct connectdata *conn,
02530                               int num,
02531                               char *buf,
02532                               size_t buffersize,
02533                               CURLcode *curlcode)
02534 {
02535   /*struct Curl_easy *data = conn->data;*/
02536   struct ssl_connect_data *connssl = &conn->ssl[num];
02537   size_t processed = 0UL;
02538   OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
02539 
02540   if(err != noErr) {
02541     switch(err) {
02542       case errSSLWouldBlock:  /* return how much we read (if anything) */
02543         if(processed)
02544           return (ssize_t)processed;
02545         *curlcode = CURLE_AGAIN;
02546         return -1L;
02547         break;
02548 
02549       /* errSSLClosedGraceful - server gracefully shut down the SSL session
02550          errSSLClosedNoNotify - server hung up on us instead of sending a
02551            closure alert notice, read() is returning 0
02552          Either way, inform the caller that the server disconnected. */
02553       case errSSLClosedGraceful:
02554       case errSSLClosedNoNotify:
02555         *curlcode = CURLE_OK;
02556         return -1L;
02557         break;
02558 
02559       default:
02560         failf(conn->data, "SSLRead() return error %d", err);
02561         *curlcode = CURLE_RECV_ERROR;
02562         return -1L;
02563         break;
02564     }
02565   }
02566   return (ssize_t)processed;
02567 }
02568 
02569 #endif /* USE_DARWINSSL */


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:02