00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "curl_setup.h"
00030
00031 #include "urldata.h"
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
00047
00048
00049
00050
00051
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
00057
00058 #define CURL_BUILD_IOS 0
00059 #define CURL_BUILD_IOS_7 0
00060 #define CURL_BUILD_MAC 1
00061
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
00068
00069
00070
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
00094
00095 #if CURL_BUILD_MAC
00096 #include <sys/sysctl.h>
00097 #endif
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
00110 #include "memdebug.h"
00111
00112
00113 #define ioErr -36
00114 #define paramErr -50
00115
00116
00117
00118 static OSStatus SocketRead(SSLConnectionRef connection,
00119 void *data,
00120
00121
00122 size_t *dataLength)
00123 {
00124 size_t bytesToGo = *dataLength;
00125 size_t initLen = bytesToGo;
00126 UInt8 *currData = (UInt8 *)data;
00127
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
00142 theErr = errno;
00143 if(rrtn == 0) {
00144
00145 rtn = errSSLClosedGraceful;
00146 }
00147 else
00148 switch(theErr) {
00149 case ENOENT:
00150
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
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)
00185 {
00186 size_t bytesSent = 0;
00187
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
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
00314
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
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
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
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
00486 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
00487
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
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
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
00672 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
00673
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
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
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
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
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
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
00810
00811
00812
00813
00814
00815 CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
00816 {
00817 CFStringRef server_cert_summary = CFSTR("(null)");
00818
00819 #if CURL_BUILD_IOS
00820
00821 server_cert_summary = SecCertificateCopySubjectSummary(cert);
00822 #else
00823 #if CURL_BUILD_MAC_10_7
00824
00825 if(SecCertificateCopyLongDescription != NULL)
00826 server_cert_summary =
00827 SecCertificateCopyLongDescription(NULL, cert, NULL);
00828 else
00829 #endif
00830 #if CURL_BUILD_MAC_10_6
00831
00832 if(SecCertificateCopySubjectSummary != NULL)
00833 server_cert_summary = SecCertificateCopySubjectSummary(cert);
00834 else
00835 #endif
00836
00837 (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
00838 #endif
00839 return server_cert_summary;
00840 }
00841
00842 #if CURL_SUPPORT_MAC_10_6
00843
00844
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
00855 attr_list.count = 1L;
00856 attr_list.attr = &attr;
00857
00858
00859 attr.tag = kSecLabelItemAttr;
00860 attr.data = label;
00861 attr.length = (UInt32)strlen(label);
00862
00863
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
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
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
00895
00896
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
00905 values[0] = kSecClassIdentity;
00906 keys[0] = kSecClass;
00907 values[1] = kCFBooleanTrue;
00908 keys[1] = kSecReturnRef;
00909 values[2] = kSecMatchLimitAll;
00910
00911 keys[2] = kSecMatchLimit;
00912
00913 values[3] = SecPolicyCreateSSL(false, NULL);
00914 keys[3] = kSecMatchPolicy;
00915
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
00925 status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
00926
00927
00928
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
00960 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
00961 #endif
00962 }
00963 #elif CURL_SUPPORT_MAC_10_6
00964
00965
00966 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
00967 #endif
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
00983
00984
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
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
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
01012 if(password)
01013 CFRelease(password);
01014 CFRelease(pkcs_url);
01015 return status;
01016 }
01017
01018
01019
01020
01021
01022
01023
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
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
01062
01063 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
01064 if(SSLCreateContext != NULL) {
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
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
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
01094 connssl->ssl_write_buffered_length = 0UL;
01095
01096
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
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
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
01254
01255
01256
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
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:
01310 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
01311 "and its private key.", ssl_cert);
01312 break;
01313 case -26275: case -25257:
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:
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
01336
01337
01338
01339 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355 #if CURL_BUILD_MAC
01356 if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
01357 #else
01358 if(SSLSetSessionOption != NULL) {
01359 #endif
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
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
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
01403
01404
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
01425
01426
01427
01428
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
01438
01439
01440
01441 if(darwinver_maj == 12 && darwinver_min <= 3 &&
01442 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
01443 continue;
01444 }
01445 #endif
01446 switch(all_ciphers[i]) {
01447
01448 case SSL_NULL_WITH_NULL_NULL:
01449 case SSL_RSA_WITH_NULL_MD5:
01450 case SSL_RSA_WITH_NULL_SHA:
01451 case 0x003B:
01452 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
01453 case 0xC001:
01454 case 0xC006:
01455 case 0xC00B:
01456 case 0xC010:
01457 case 0x002C:
01458 case 0x002D:
01459 case 0x002E:
01460 case 0x00B0:
01461 case 0x00B1:
01462 case 0x00B4:
01463 case 0x00B5:
01464 case 0x00B8:
01465 case 0x00B9:
01466
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:
01475 case 0xC016:
01476 case 0xC017:
01477 case 0xC018:
01478 case 0xC019:
01479 case 0x006C:
01480 case 0x006D:
01481 case 0x00A6:
01482 case 0x00A7:
01483
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
01497 case SSL_RSA_WITH_IDEA_CBC_SHA:
01498 case SSL_RSA_WITH_IDEA_CBC_MD5:
01499
01500 case SSL_RSA_WITH_RC4_128_MD5:
01501 case SSL_RSA_WITH_RC4_128_SHA:
01502 case 0xC002:
01503 case 0xC007:
01504 case 0xC00C:
01505 case 0xC011:
01506 case 0x008A:
01507 case 0x008E:
01508 case 0x0092:
01509 break;
01510 default:
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
01533
01534 if(SSLSetSessionOption != NULL) {
01535
01536 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
01537 !data->set.ssl.enable_beast);
01538 SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
01539 data->set.ssl.falsestart);
01540 }
01541 #endif
01542
01543
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
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
01559 infof(data, "SSL re-using session ID\n");
01560 }
01561
01562
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
01594
01595
01596
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
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
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
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
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
01794
01795
01796
01797
01798
01799
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
01814
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
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
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
01912 err = SSLHandshake(connssl->ssl_ctx);
01913
01914 if(err != noErr) {
01915 switch(err) {
01916 case errSSLWouldBlock:
01917 connssl->connecting_state = connssl->ssl_direction ?
01918 ssl_connect_2_writing : ssl_connect_2_reading;
01919 return CURLE_OK;
01920
01921
01922
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
01931 return darwinssl_connect_step2(conn, sockindex);
01932
01933
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
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
01967
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
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
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
02000 connssl->connecting_state = ssl_connect_3;
02001
02002
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
02052
02053
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
02059
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
02078
02079
02080
02081
02082
02083 if(SecTrustEvaluateAsync != NULL) {
02084 #pragma unused(server_certs)
02085 err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
02086
02087
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
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
02128 }
02129 #endif
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
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
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
02179 timeout_ms = Curl_timeleft(data, NULL, TRUE);
02180
02181 if(timeout_ms < 0) {
02182
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
02197 timeout_ms = Curl_timeleft(data, NULL, TRUE);
02198
02199 if(timeout_ms < 0) {
02200
02201 failf(data, "SSL connection timeout");
02202 return CURLE_OPERATION_TIMEDOUT;
02203 }
02204
02205
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
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
02228 failf(data, "SSL connection timeout");
02229 return CURLE_OPERATION_TIMEDOUT;
02230 }
02231 }
02232
02233 }
02234
02235
02236
02237
02238
02239
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 }
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
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
02310 #else
02311 (void)SSLDisposeContext(connssl->ssl_ctx);
02312 #endif
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
02342 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
02343 rc = -1;
02344 break;
02345 }
02346
02347 if(!what) {
02348 failf(data, "SSL shutdown timeout");
02349 break;
02350 }
02351
02352
02353
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
02374
02375
02376
02377
02378
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
02389
02390
02391
02392
02393
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) {
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
02431
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,
02446 size_t tmplen,
02447 unsigned char *md5sum,
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
02470 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
02471 size_t processed = 0UL;
02472 OSStatus err;
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489 if(connssl->ssl_write_buffered_length) {
02490
02491 err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
02492 switch(err) {
02493 case noErr:
02494
02495
02496 processed = connssl->ssl_write_buffered_length;
02497 connssl->ssl_write_buffered_length = 0UL;
02498 break;
02499 case errSSLWouldBlock:
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
02510 err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
02511 if(err != noErr) {
02512 switch(err) {
02513 case errSSLWouldBlock:
02514
02515
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
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:
02543 if(processed)
02544 return (ssize_t)processed;
02545 *curlcode = CURLE_AGAIN;
02546 return -1L;
02547 break;
02548
02549
02550
02551
02552
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