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