Return to openssl.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / vtls |
1.1 ! misho 1: /*************************************************************************** ! 2: * _ _ ____ _ ! 3: * Project ___| | | | _ \| | ! 4: * / __| | | | |_) | | ! 5: * | (__| |_| | _ <| |___ ! 6: * \___|\___/|_| \_\_____| ! 7: * ! 8: * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. ! 9: * ! 10: * This software is licensed as described in the file COPYING, which ! 11: * you should have received as part of this distribution. The terms ! 12: * are also available at https://curl.haxx.se/docs/copyright.html. ! 13: * ! 14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell ! 15: * copies of the Software, and permit persons to whom the Software is ! 16: * furnished to do so, under the terms of the COPYING file. ! 17: * ! 18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ! 19: * KIND, either express or implied. ! 20: * ! 21: ***************************************************************************/ ! 22: ! 23: /* ! 24: * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code ! 25: * but vtls.c should ever call or use these functions. ! 26: */ ! 27: ! 28: #include "curl_setup.h" ! 29: ! 30: #ifdef USE_OPENSSL ! 31: ! 32: #include <limits.h> ! 33: ! 34: #include "urldata.h" ! 35: #include "sendf.h" ! 36: #include "formdata.h" /* for the boundary function */ ! 37: #include "url.h" /* for the ssl config check function */ ! 38: #include "inet_pton.h" ! 39: #include "openssl.h" ! 40: #include "connect.h" ! 41: #include "slist.h" ! 42: #include "select.h" ! 43: #include "vtls.h" ! 44: #include "strcase.h" ! 45: #include "hostcheck.h" ! 46: #include "multiif.h" ! 47: #include "strerror.h" ! 48: #include "curl_printf.h" ! 49: #include <openssl/ssl.h> ! 50: #include <openssl/rand.h> ! 51: #include <openssl/x509v3.h> ! 52: #ifndef OPENSSL_NO_DSA ! 53: #include <openssl/dsa.h> ! 54: #endif ! 55: #include <openssl/dh.h> ! 56: #include <openssl/err.h> ! 57: #include <openssl/md5.h> ! 58: #include <openssl/conf.h> ! 59: #include <openssl/bn.h> ! 60: #include <openssl/rsa.h> ! 61: #include <openssl/bio.h> ! 62: #include <openssl/buffer.h> ! 63: #include <openssl/pkcs12.h> ! 64: ! 65: #ifdef USE_AMISSL ! 66: #include "amigaos.h" ! 67: #endif ! 68: ! 69: #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP) ! 70: #include <openssl/ocsp.h> ! 71: #endif ! 72: ! 73: #if (OPENSSL_VERSION_NUMBER >= 0x0090700fL) && /* 0.9.7 or later */ \ ! 74: !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_UI_CONSOLE) ! 75: #define USE_OPENSSL_ENGINE ! 76: #include <openssl/engine.h> ! 77: #endif ! 78: ! 79: #include "warnless.h" ! 80: #include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */ ! 81: ! 82: /* The last #include files should be: */ ! 83: #include "curl_memory.h" ! 84: #include "memdebug.h" ! 85: ! 86: /* Uncomment the ALLOW_RENEG line to a real #define if you want to allow TLS ! 87: renegotiations when built with BoringSSL. Renegotiating is non-compliant ! 88: with HTTP/2 and "an extremely dangerous protocol feature". Beware. ! 89: ! 90: #define ALLOW_RENEG 1 ! 91: */ ! 92: ! 93: #ifndef OPENSSL_VERSION_NUMBER ! 94: #error "OPENSSL_VERSION_NUMBER not defined" ! 95: #endif ! 96: ! 97: #ifdef USE_OPENSSL_ENGINE ! 98: #include <openssl/ui.h> ! 99: #endif ! 100: ! 101: #if OPENSSL_VERSION_NUMBER >= 0x00909000L ! 102: #define SSL_METHOD_QUAL const ! 103: #else ! 104: #define SSL_METHOD_QUAL ! 105: #endif ! 106: ! 107: #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) ! 108: #define HAVE_ERR_REMOVE_THREAD_STATE 1 ! 109: #endif ! 110: ! 111: #if !defined(HAVE_SSLV2_CLIENT_METHOD) || \ ! 112: OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */ ! 113: #undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */ ! 114: #define OPENSSL_NO_SSL2 ! 115: #endif ! 116: ! 117: #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \ ! 118: !(defined(LIBRESSL_VERSION_NUMBER) && \ ! 119: LIBRESSL_VERSION_NUMBER < 0x20700000L) ! 120: #define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER ! 121: #define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */ ! 122: #define HAVE_OPAQUE_EVP_PKEY 1 /* since 1.1.0 -pre3 */ ! 123: #define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */ ! 124: #define CONST_EXTS const ! 125: #define HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED 1 ! 126: ! 127: /* funny typecast define due to difference in API */ ! 128: #ifdef LIBRESSL_VERSION_NUMBER ! 129: #define ARG2_X509_signature_print (X509_ALGOR *) ! 130: #else ! 131: #define ARG2_X509_signature_print ! 132: #endif ! 133: ! 134: #else ! 135: /* For OpenSSL before 1.1.0 */ ! 136: #define ASN1_STRING_get0_data(x) ASN1_STRING_data(x) ! 137: #define X509_get0_notBefore(x) X509_get_notBefore(x) ! 138: #define X509_get0_notAfter(x) X509_get_notAfter(x) ! 139: #define CONST_EXTS /* nope */ ! 140: #ifndef LIBRESSL_VERSION_NUMBER ! 141: #define OpenSSL_version_num() SSLeay() ! 142: #endif ! 143: #endif ! 144: ! 145: #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \ ! 146: !(defined(LIBRESSL_VERSION_NUMBER) && \ ! 147: LIBRESSL_VERSION_NUMBER < 0x20700000L) ! 148: #define HAVE_X509_GET0_SIGNATURE 1 ! 149: #endif ! 150: ! 151: #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) /* 1.0.2 or later */ ! 152: #define HAVE_SSL_GET_SHUTDOWN 1 ! 153: #endif ! 154: ! 155: #if OPENSSL_VERSION_NUMBER >= 0x10002003L && \ ! 156: OPENSSL_VERSION_NUMBER <= 0x10002FFFL && \ ! 157: !defined(OPENSSL_NO_COMP) ! 158: #define HAVE_SSL_COMP_FREE_COMPRESSION_METHODS 1 ! 159: #endif ! 160: ! 161: #if (OPENSSL_VERSION_NUMBER < 0x0090808fL) ! 162: /* not present in older OpenSSL */ ! 163: #define OPENSSL_load_builtin_modules(x) ! 164: #endif ! 165: ! 166: /* ! 167: * Whether SSL_CTX_set_keylog_callback is available. ! 168: * OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287 ! 169: * BoringSSL: supported since d28f59c27bac (committed 2015-11-19) ! 170: * LibreSSL: unsupported in at least 2.7.2 (explicitly check for it since it ! 171: * lies and pretends to be OpenSSL 2.0.0). ! 172: */ ! 173: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \ ! 174: !defined(LIBRESSL_VERSION_NUMBER)) || \ ! 175: defined(OPENSSL_IS_BORINGSSL) ! 176: #define HAVE_KEYLOG_CALLBACK ! 177: #endif ! 178: ! 179: /* Whether SSL_CTX_set_ciphersuites is available. ! 180: * OpenSSL: supported since 1.1.1 (commit a53b5be6a05) ! 181: * BoringSSL: no ! 182: * LibreSSL: no ! 183: */ ! 184: #if ((OPENSSL_VERSION_NUMBER >= 0x10101000L) && \ ! 185: !defined(LIBRESSL_VERSION_NUMBER) && \ ! 186: !defined(OPENSSL_IS_BORINGSSL)) ! 187: #define HAVE_SSL_CTX_SET_CIPHERSUITES ! 188: #define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH ! 189: #endif ! 190: ! 191: #if defined(LIBRESSL_VERSION_NUMBER) ! 192: #define OSSL_PACKAGE "LibreSSL" ! 193: #elif defined(OPENSSL_IS_BORINGSSL) ! 194: #define OSSL_PACKAGE "BoringSSL" ! 195: #else ! 196: #define OSSL_PACKAGE "OpenSSL" ! 197: #endif ! 198: ! 199: #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) ! 200: /* up2date versions of OpenSSL maintain the default reasonably secure without ! 201: * breaking compatibility, so it is better not to override the default by curl ! 202: */ ! 203: #define DEFAULT_CIPHER_SELECTION NULL ! 204: #else ! 205: /* ... but it is not the case with old versions of OpenSSL */ ! 206: #define DEFAULT_CIPHER_SELECTION \ ! 207: "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH" ! 208: #endif ! 209: ! 210: #define ENABLE_SSLKEYLOGFILE ! 211: ! 212: #ifdef ENABLE_SSLKEYLOGFILE ! 213: typedef struct ssl_tap_state { ! 214: int master_key_length; ! 215: unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; ! 216: unsigned char client_random[SSL3_RANDOM_SIZE]; ! 217: } ssl_tap_state_t; ! 218: #endif /* ENABLE_SSLKEYLOGFILE */ ! 219: ! 220: struct ssl_backend_data { ! 221: /* these ones requires specific SSL-types */ ! 222: SSL_CTX* ctx; ! 223: SSL* handle; ! 224: X509* server_cert; ! 225: #ifdef ENABLE_SSLKEYLOGFILE ! 226: /* tap_state holds the last seen master key if we're logging them */ ! 227: ssl_tap_state_t tap_state; ! 228: #endif ! 229: }; ! 230: ! 231: /* ! 232: * Number of bytes to read from the random number seed file. This must be ! 233: * a finite value (because some entropy "files" like /dev/urandom have ! 234: * an infinite length), but must be large enough to provide enough ! 235: * entropy to properly seed OpenSSL's PRNG. ! 236: */ ! 237: #define RAND_LOAD_LENGTH 1024 ! 238: ! 239: #ifdef ENABLE_SSLKEYLOGFILE ! 240: /* The fp for the open SSLKEYLOGFILE, or NULL if not open */ ! 241: static FILE *keylog_file_fp; ! 242: ! 243: #ifdef HAVE_KEYLOG_CALLBACK ! 244: static void ossl_keylog_callback(const SSL *ssl, const char *line) ! 245: { ! 246: (void)ssl; ! 247: ! 248: /* Using fputs here instead of fprintf since libcurl's fprintf replacement ! 249: may not be thread-safe. */ ! 250: if(keylog_file_fp && line && *line) { ! 251: char stackbuf[256]; ! 252: char *buf; ! 253: size_t linelen = strlen(line); ! 254: ! 255: if(linelen <= sizeof(stackbuf) - 2) ! 256: buf = stackbuf; ! 257: else { ! 258: buf = malloc(linelen + 2); ! 259: if(!buf) ! 260: return; ! 261: } ! 262: memcpy(buf, line, linelen); ! 263: buf[linelen] = '\n'; ! 264: buf[linelen + 1] = '\0'; ! 265: ! 266: fputs(buf, keylog_file_fp); ! 267: if(buf != stackbuf) ! 268: free(buf); ! 269: } ! 270: } ! 271: #else ! 272: #define KEYLOG_PREFIX "CLIENT_RANDOM " ! 273: #define KEYLOG_PREFIX_LEN (sizeof(KEYLOG_PREFIX) - 1) ! 274: /* ! 275: * tap_ssl_key is called by libcurl to make the CLIENT_RANDOMs if the OpenSSL ! 276: * being used doesn't have native support for doing that. ! 277: */ ! 278: static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state) ! 279: { ! 280: const char *hex = "0123456789ABCDEF"; ! 281: int pos, i; ! 282: char line[KEYLOG_PREFIX_LEN + 2 * SSL3_RANDOM_SIZE + 1 + ! 283: 2 * SSL_MAX_MASTER_KEY_LENGTH + 1 + 1]; ! 284: const SSL_SESSION *session = SSL_get_session(ssl); ! 285: unsigned char client_random[SSL3_RANDOM_SIZE]; ! 286: unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; ! 287: int master_key_length = 0; ! 288: ! 289: if(!session || !keylog_file_fp) ! 290: return; ! 291: ! 292: #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ ! 293: !(defined(LIBRESSL_VERSION_NUMBER) && \ ! 294: LIBRESSL_VERSION_NUMBER < 0x20700000L) ! 295: /* ssl->s3 is not checked in openssl 1.1.0-pre6, but let's assume that ! 296: * we have a valid SSL context if we have a non-NULL session. */ ! 297: SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE); ! 298: master_key_length = (int) ! 299: SSL_SESSION_get_master_key(session, master_key, SSL_MAX_MASTER_KEY_LENGTH); ! 300: #else ! 301: if(ssl->s3 && session->master_key_length > 0) { ! 302: master_key_length = session->master_key_length; ! 303: memcpy(master_key, session->master_key, session->master_key_length); ! 304: memcpy(client_random, ssl->s3->client_random, SSL3_RANDOM_SIZE); ! 305: } ! 306: #endif ! 307: ! 308: if(master_key_length <= 0) ! 309: return; ! 310: ! 311: /* Skip writing keys if there is no key or it did not change. */ ! 312: if(state->master_key_length == master_key_length && ! 313: !memcmp(state->master_key, master_key, master_key_length) && ! 314: !memcmp(state->client_random, client_random, SSL3_RANDOM_SIZE)) { ! 315: return; ! 316: } ! 317: ! 318: state->master_key_length = master_key_length; ! 319: memcpy(state->master_key, master_key, master_key_length); ! 320: memcpy(state->client_random, client_random, SSL3_RANDOM_SIZE); ! 321: ! 322: memcpy(line, KEYLOG_PREFIX, KEYLOG_PREFIX_LEN); ! 323: pos = KEYLOG_PREFIX_LEN; ! 324: ! 325: /* Client Random for SSLv3/TLS */ ! 326: for(i = 0; i < SSL3_RANDOM_SIZE; i++) { ! 327: line[pos++] = hex[client_random[i] >> 4]; ! 328: line[pos++] = hex[client_random[i] & 0xF]; ! 329: } ! 330: line[pos++] = ' '; ! 331: ! 332: /* Master Secret (size is at most SSL_MAX_MASTER_KEY_LENGTH) */ ! 333: for(i = 0; i < master_key_length; i++) { ! 334: line[pos++] = hex[master_key[i] >> 4]; ! 335: line[pos++] = hex[master_key[i] & 0xF]; ! 336: } ! 337: line[pos++] = '\n'; ! 338: line[pos] = '\0'; ! 339: ! 340: /* Using fputs here instead of fprintf since libcurl's fprintf replacement ! 341: may not be thread-safe. */ ! 342: fputs(line, keylog_file_fp); ! 343: } ! 344: #endif /* !HAVE_KEYLOG_CALLBACK */ ! 345: #endif /* ENABLE_SSLKEYLOGFILE */ ! 346: ! 347: static const char *SSL_ERROR_to_str(int err) ! 348: { ! 349: switch(err) { ! 350: case SSL_ERROR_NONE: ! 351: return "SSL_ERROR_NONE"; ! 352: case SSL_ERROR_SSL: ! 353: return "SSL_ERROR_SSL"; ! 354: case SSL_ERROR_WANT_READ: ! 355: return "SSL_ERROR_WANT_READ"; ! 356: case SSL_ERROR_WANT_WRITE: ! 357: return "SSL_ERROR_WANT_WRITE"; ! 358: case SSL_ERROR_WANT_X509_LOOKUP: ! 359: return "SSL_ERROR_WANT_X509_LOOKUP"; ! 360: case SSL_ERROR_SYSCALL: ! 361: return "SSL_ERROR_SYSCALL"; ! 362: case SSL_ERROR_ZERO_RETURN: ! 363: return "SSL_ERROR_ZERO_RETURN"; ! 364: case SSL_ERROR_WANT_CONNECT: ! 365: return "SSL_ERROR_WANT_CONNECT"; ! 366: case SSL_ERROR_WANT_ACCEPT: ! 367: return "SSL_ERROR_WANT_ACCEPT"; ! 368: #if defined(SSL_ERROR_WANT_ASYNC) ! 369: case SSL_ERROR_WANT_ASYNC: ! 370: return "SSL_ERROR_WANT_ASYNC"; ! 371: #endif ! 372: #if defined(SSL_ERROR_WANT_ASYNC_JOB) ! 373: case SSL_ERROR_WANT_ASYNC_JOB: ! 374: return "SSL_ERROR_WANT_ASYNC_JOB"; ! 375: #endif ! 376: #if defined(SSL_ERROR_WANT_EARLY) ! 377: case SSL_ERROR_WANT_EARLY: ! 378: return "SSL_ERROR_WANT_EARLY"; ! 379: #endif ! 380: default: ! 381: return "SSL_ERROR unknown"; ! 382: } ! 383: } ! 384: ! 385: /* Return error string for last OpenSSL error ! 386: */ ! 387: static char *ossl_strerror(unsigned long error, char *buf, size_t size) ! 388: { ! 389: if(size) ! 390: *buf = '\0'; ! 391: ! 392: #ifdef OPENSSL_IS_BORINGSSL ! 393: ERR_error_string_n((uint32_t)error, buf, size); ! 394: #else ! 395: ERR_error_string_n(error, buf, size); ! 396: #endif ! 397: ! 398: if(size > 1 && !*buf) { ! 399: strncpy(buf, (error ? "Unknown error" : "No error"), size); ! 400: buf[size - 1] = '\0'; ! 401: } ! 402: ! 403: return buf; ! 404: } ! 405: ! 406: /* Return an extra data index for the connection data. ! 407: * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). ! 408: */ ! 409: static int ossl_get_ssl_conn_index(void) ! 410: { ! 411: static int ssl_ex_data_conn_index = -1; ! 412: if(ssl_ex_data_conn_index < 0) { ! 413: ssl_ex_data_conn_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); ! 414: } ! 415: return ssl_ex_data_conn_index; ! 416: } ! 417: ! 418: /* Return an extra data index for the sockindex. ! 419: * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). ! 420: */ ! 421: static int ossl_get_ssl_sockindex_index(void) ! 422: { ! 423: static int ssl_ex_data_sockindex_index = -1; ! 424: if(ssl_ex_data_sockindex_index < 0) { ! 425: ssl_ex_data_sockindex_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, ! 426: NULL); ! 427: } ! 428: return ssl_ex_data_sockindex_index; ! 429: } ! 430: ! 431: static int passwd_callback(char *buf, int num, int encrypting, ! 432: void *global_passwd) ! 433: { ! 434: DEBUGASSERT(0 == encrypting); ! 435: ! 436: if(!encrypting) { ! 437: int klen = curlx_uztosi(strlen((char *)global_passwd)); ! 438: if(num > klen) { ! 439: memcpy(buf, global_passwd, klen + 1); ! 440: return klen; ! 441: } ! 442: } ! 443: return 0; ! 444: } ! 445: ! 446: /* ! 447: * rand_enough() returns TRUE if we have seeded the random engine properly. ! 448: */ ! 449: static bool rand_enough(void) ! 450: { ! 451: return (0 != RAND_status()) ? TRUE : FALSE; ! 452: } ! 453: ! 454: static CURLcode Curl_ossl_seed(struct Curl_easy *data) ! 455: { ! 456: /* we have the "SSL is seeded" boolean static to prevent multiple ! 457: time-consuming seedings in vain */ ! 458: static bool ssl_seeded = FALSE; ! 459: char fname[256]; ! 460: ! 461: if(ssl_seeded) ! 462: return CURLE_OK; ! 463: ! 464: if(rand_enough()) { ! 465: /* OpenSSL 1.1.0+ will return here */ ! 466: ssl_seeded = TRUE; ! 467: return CURLE_OK; ! 468: } ! 469: ! 470: #ifndef RANDOM_FILE ! 471: /* if RANDOM_FILE isn't defined, we only perform this if an option tells ! 472: us to! */ ! 473: if(data->set.str[STRING_SSL_RANDOM_FILE]) ! 474: #define RANDOM_FILE "" /* doesn't matter won't be used */ ! 475: #endif ! 476: { ! 477: /* let the option override the define */ ! 478: RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]? ! 479: data->set.str[STRING_SSL_RANDOM_FILE]: ! 480: RANDOM_FILE), ! 481: RAND_LOAD_LENGTH); ! 482: if(rand_enough()) ! 483: return CURLE_OK; ! 484: } ! 485: ! 486: #if defined(HAVE_RAND_EGD) ! 487: /* only available in OpenSSL 0.9.5 and later */ ! 488: /* EGD_SOCKET is set at configure time or not at all */ ! 489: #ifndef EGD_SOCKET ! 490: /* If we don't have the define set, we only do this if the egd-option ! 491: is set */ ! 492: if(data->set.str[STRING_SSL_EGDSOCKET]) ! 493: #define EGD_SOCKET "" /* doesn't matter won't be used */ ! 494: #endif ! 495: { ! 496: /* If there's an option and a define, the option overrides the ! 497: define */ ! 498: int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]? ! 499: data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET); ! 500: if(-1 != ret) { ! 501: if(rand_enough()) ! 502: return CURLE_OK; ! 503: } ! 504: } ! 505: #endif ! 506: ! 507: /* fallback to a custom seeding of the PRNG using a hash based on a current ! 508: time */ ! 509: do { ! 510: unsigned char randb[64]; ! 511: size_t len = sizeof(randb); ! 512: size_t i, i_max; ! 513: for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) { ! 514: struct curltime tv = Curl_now(); ! 515: Curl_wait_ms(1); ! 516: tv.tv_sec *= i + 1; ! 517: tv.tv_usec *= (unsigned int)i + 2; ! 518: tv.tv_sec ^= ((Curl_now().tv_sec + Curl_now().tv_usec) * ! 519: (i + 3)) << 8; ! 520: tv.tv_usec ^= (unsigned int) ((Curl_now().tv_sec + ! 521: Curl_now().tv_usec) * ! 522: (i + 4)) << 16; ! 523: memcpy(&randb[i * sizeof(struct curltime)], &tv, ! 524: sizeof(struct curltime)); ! 525: } ! 526: RAND_add(randb, (int)len, (double)len/2); ! 527: } while(!rand_enough()); ! 528: ! 529: /* generates a default path for the random seed file */ ! 530: fname[0] = 0; /* blank it first */ ! 531: RAND_file_name(fname, sizeof(fname)); ! 532: if(fname[0]) { ! 533: /* we got a file name to try */ ! 534: RAND_load_file(fname, RAND_LOAD_LENGTH); ! 535: if(rand_enough()) ! 536: return CURLE_OK; ! 537: } ! 538: ! 539: infof(data, "libcurl is now using a weak random seed!\n"); ! 540: return (rand_enough() ? CURLE_OK : ! 541: CURLE_SSL_CONNECT_ERROR /* confusing error code */); ! 542: } ! 543: ! 544: #ifndef SSL_FILETYPE_ENGINE ! 545: #define SSL_FILETYPE_ENGINE 42 ! 546: #endif ! 547: #ifndef SSL_FILETYPE_PKCS12 ! 548: #define SSL_FILETYPE_PKCS12 43 ! 549: #endif ! 550: static int do_file_type(const char *type) ! 551: { ! 552: if(!type || !type[0]) ! 553: return SSL_FILETYPE_PEM; ! 554: if(strcasecompare(type, "PEM")) ! 555: return SSL_FILETYPE_PEM; ! 556: if(strcasecompare(type, "DER")) ! 557: return SSL_FILETYPE_ASN1; ! 558: if(strcasecompare(type, "ENG")) ! 559: return SSL_FILETYPE_ENGINE; ! 560: if(strcasecompare(type, "P12")) ! 561: return SSL_FILETYPE_PKCS12; ! 562: return -1; ! 563: } ! 564: ! 565: #ifdef USE_OPENSSL_ENGINE ! 566: /* ! 567: * Supply default password to the engine user interface conversation. ! 568: * The password is passed by OpenSSL engine from ENGINE_load_private_key() ! 569: * last argument to the ui and can be obtained by UI_get0_user_data(ui) here. ! 570: */ ! 571: static int ssl_ui_reader(UI *ui, UI_STRING *uis) ! 572: { ! 573: const char *password; ! 574: switch(UI_get_string_type(uis)) { ! 575: case UIT_PROMPT: ! 576: case UIT_VERIFY: ! 577: password = (const char *)UI_get0_user_data(ui); ! 578: if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) { ! 579: UI_set_result(ui, uis, password); ! 580: return 1; ! 581: } ! 582: default: ! 583: break; ! 584: } ! 585: return (UI_method_get_reader(UI_OpenSSL()))(ui, uis); ! 586: } ! 587: ! 588: /* ! 589: * Suppress interactive request for a default password if available. ! 590: */ ! 591: static int ssl_ui_writer(UI *ui, UI_STRING *uis) ! 592: { ! 593: switch(UI_get_string_type(uis)) { ! 594: case UIT_PROMPT: ! 595: case UIT_VERIFY: ! 596: if(UI_get0_user_data(ui) && ! 597: (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) { ! 598: return 1; ! 599: } ! 600: default: ! 601: break; ! 602: } ! 603: return (UI_method_get_writer(UI_OpenSSL()))(ui, uis); ! 604: } ! 605: ! 606: /* ! 607: * Check if a given string is a PKCS#11 URI ! 608: */ ! 609: static bool is_pkcs11_uri(const char *string) ! 610: { ! 611: return (string && strncasecompare(string, "pkcs11:", 7)); ! 612: } ! 613: ! 614: #endif ! 615: ! 616: static CURLcode Curl_ossl_set_engine(struct Curl_easy *data, ! 617: const char *engine); ! 618: ! 619: static ! 620: int cert_stuff(struct connectdata *conn, ! 621: SSL_CTX* ctx, ! 622: char *cert_file, ! 623: const char *cert_type, ! 624: char *key_file, ! 625: const char *key_type, ! 626: char *key_passwd) ! 627: { ! 628: struct Curl_easy *data = conn->data; ! 629: char error_buffer[256]; ! 630: bool check_privkey = TRUE; ! 631: ! 632: int file_type = do_file_type(cert_type); ! 633: ! 634: if(cert_file || (file_type == SSL_FILETYPE_ENGINE)) { ! 635: SSL *ssl; ! 636: X509 *x509; ! 637: int cert_done = 0; ! 638: ! 639: if(key_passwd) { ! 640: /* set the password in the callback userdata */ ! 641: SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd); ! 642: /* Set passwd callback: */ ! 643: SSL_CTX_set_default_passwd_cb(ctx, passwd_callback); ! 644: } ! 645: ! 646: ! 647: switch(file_type) { ! 648: case SSL_FILETYPE_PEM: ! 649: /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ ! 650: if(SSL_CTX_use_certificate_chain_file(ctx, ! 651: cert_file) != 1) { ! 652: failf(data, ! 653: "could not load PEM client certificate, " OSSL_PACKAGE ! 654: " error %s, " ! 655: "(no key found, wrong pass phrase, or wrong file format?)", ! 656: ossl_strerror(ERR_get_error(), error_buffer, ! 657: sizeof(error_buffer)) ); ! 658: return 0; ! 659: } ! 660: break; ! 661: ! 662: case SSL_FILETYPE_ASN1: ! 663: /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but ! 664: we use the case above for PEM so this can only be performed with ! 665: ASN1 files. */ ! 666: if(SSL_CTX_use_certificate_file(ctx, ! 667: cert_file, ! 668: file_type) != 1) { ! 669: failf(data, ! 670: "could not load ASN1 client certificate, " OSSL_PACKAGE ! 671: " error %s, " ! 672: "(no key found, wrong pass phrase, or wrong file format?)", ! 673: ossl_strerror(ERR_get_error(), error_buffer, ! 674: sizeof(error_buffer)) ); ! 675: return 0; ! 676: } ! 677: break; ! 678: case SSL_FILETYPE_ENGINE: ! 679: #if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME) ! 680: { ! 681: /* Implicitly use pkcs11 engine if none was provided and the ! 682: * cert_file is a PKCS#11 URI */ ! 683: if(!data->state.engine) { ! 684: if(is_pkcs11_uri(cert_file)) { ! 685: if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) { ! 686: return 0; ! 687: } ! 688: } ! 689: } ! 690: ! 691: if(data->state.engine) { ! 692: const char *cmd_name = "LOAD_CERT_CTRL"; ! 693: struct { ! 694: const char *cert_id; ! 695: X509 *cert; ! 696: } params; ! 697: ! 698: params.cert_id = cert_file; ! 699: params.cert = NULL; ! 700: ! 701: /* Does the engine supports LOAD_CERT_CTRL ? */ ! 702: if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME, ! 703: 0, (void *)cmd_name, NULL)) { ! 704: failf(data, "ssl engine does not support loading certificates"); ! 705: return 0; ! 706: } ! 707: ! 708: /* Load the certificate from the engine */ ! 709: if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name, ! 710: 0, ¶ms, NULL, 1)) { ! 711: failf(data, "ssl engine cannot load client cert with id" ! 712: " '%s' [%s]", cert_file, ! 713: ossl_strerror(ERR_get_error(), error_buffer, ! 714: sizeof(error_buffer))); ! 715: return 0; ! 716: } ! 717: ! 718: if(!params.cert) { ! 719: failf(data, "ssl engine didn't initialized the certificate " ! 720: "properly."); ! 721: return 0; ! 722: } ! 723: ! 724: if(SSL_CTX_use_certificate(ctx, params.cert) != 1) { ! 725: failf(data, "unable to set client certificate"); ! 726: X509_free(params.cert); ! 727: return 0; ! 728: } ! 729: X509_free(params.cert); /* we don't need the handle any more... */ ! 730: } ! 731: else { ! 732: failf(data, "crypto engine not set, can't load certificate"); ! 733: return 0; ! 734: } ! 735: } ! 736: break; ! 737: #else ! 738: failf(data, "file type ENG for certificate not implemented"); ! 739: return 0; ! 740: #endif ! 741: ! 742: case SSL_FILETYPE_PKCS12: ! 743: { ! 744: BIO *fp = NULL; ! 745: PKCS12 *p12 = NULL; ! 746: EVP_PKEY *pri; ! 747: STACK_OF(X509) *ca = NULL; ! 748: ! 749: fp = BIO_new(BIO_s_file()); ! 750: if(fp == NULL) { ! 751: failf(data, ! 752: "BIO_new return NULL, " OSSL_PACKAGE ! 753: " error %s", ! 754: ossl_strerror(ERR_get_error(), error_buffer, ! 755: sizeof(error_buffer)) ); ! 756: return 0; ! 757: } ! 758: ! 759: if(BIO_read_filename(fp, cert_file) <= 0) { ! 760: failf(data, "could not open PKCS12 file '%s'", cert_file); ! 761: BIO_free(fp); ! 762: return 0; ! 763: } ! 764: p12 = d2i_PKCS12_bio(fp, NULL); ! 765: BIO_free(fp); ! 766: ! 767: if(!p12) { ! 768: failf(data, "error reading PKCS12 file '%s'", cert_file); ! 769: return 0; ! 770: } ! 771: ! 772: PKCS12_PBE_add(); ! 773: ! 774: if(!PKCS12_parse(p12, key_passwd, &pri, &x509, ! 775: &ca)) { ! 776: failf(data, ! 777: "could not parse PKCS12 file, check password, " OSSL_PACKAGE ! 778: " error %s", ! 779: ossl_strerror(ERR_get_error(), error_buffer, ! 780: sizeof(error_buffer)) ); ! 781: PKCS12_free(p12); ! 782: return 0; ! 783: } ! 784: ! 785: PKCS12_free(p12); ! 786: ! 787: if(SSL_CTX_use_certificate(ctx, x509) != 1) { ! 788: failf(data, ! 789: "could not load PKCS12 client certificate, " OSSL_PACKAGE ! 790: " error %s", ! 791: ossl_strerror(ERR_get_error(), error_buffer, ! 792: sizeof(error_buffer)) ); ! 793: goto fail; ! 794: } ! 795: ! 796: if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) { ! 797: failf(data, "unable to use private key from PKCS12 file '%s'", ! 798: cert_file); ! 799: goto fail; ! 800: } ! 801: ! 802: if(!SSL_CTX_check_private_key (ctx)) { ! 803: failf(data, "private key from PKCS12 file '%s' " ! 804: "does not match certificate in same file", cert_file); ! 805: goto fail; ! 806: } ! 807: /* Set Certificate Verification chain */ ! 808: if(ca) { ! 809: while(sk_X509_num(ca)) { ! 810: /* ! 811: * Note that sk_X509_pop() is used below to make sure the cert is ! 812: * removed from the stack properly before getting passed to ! 813: * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously ! 814: * we used sk_X509_value() instead, but then we'd clean it in the ! 815: * subsequent sk_X509_pop_free() call. ! 816: */ ! 817: X509 *x = sk_X509_pop(ca); ! 818: if(!SSL_CTX_add_client_CA(ctx, x)) { ! 819: X509_free(x); ! 820: failf(data, "cannot add certificate to client CA list"); ! 821: goto fail; ! 822: } ! 823: if(!SSL_CTX_add_extra_chain_cert(ctx, x)) { ! 824: X509_free(x); ! 825: failf(data, "cannot add certificate to certificate chain"); ! 826: goto fail; ! 827: } ! 828: } ! 829: } ! 830: ! 831: cert_done = 1; ! 832: fail: ! 833: EVP_PKEY_free(pri); ! 834: X509_free(x509); ! 835: #ifdef USE_AMISSL ! 836: sk_X509_pop_free(ca, Curl_amiga_X509_free); ! 837: #else ! 838: sk_X509_pop_free(ca, X509_free); ! 839: #endif ! 840: if(!cert_done) ! 841: return 0; /* failure! */ ! 842: break; ! 843: } ! 844: default: ! 845: failf(data, "not supported file type '%s' for certificate", cert_type); ! 846: return 0; ! 847: } ! 848: ! 849: if(!key_file) ! 850: key_file = cert_file; ! 851: else ! 852: file_type = do_file_type(key_type); ! 853: ! 854: switch(file_type) { ! 855: case SSL_FILETYPE_PEM: ! 856: if(cert_done) ! 857: break; ! 858: /* FALLTHROUGH */ ! 859: case SSL_FILETYPE_ASN1: ! 860: if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) { ! 861: failf(data, "unable to set private key file: '%s' type %s", ! 862: key_file, key_type?key_type:"PEM"); ! 863: return 0; ! 864: } ! 865: break; ! 866: case SSL_FILETYPE_ENGINE: ! 867: #ifdef USE_OPENSSL_ENGINE ! 868: { /* XXXX still needs some work */ ! 869: EVP_PKEY *priv_key = NULL; ! 870: ! 871: /* Implicitly use pkcs11 engine if none was provided and the ! 872: * key_file is a PKCS#11 URI */ ! 873: if(!data->state.engine) { ! 874: if(is_pkcs11_uri(key_file)) { ! 875: if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) { ! 876: return 0; ! 877: } ! 878: } ! 879: } ! 880: ! 881: if(data->state.engine) { ! 882: UI_METHOD *ui_method = ! 883: UI_create_method((char *)"curl user interface"); ! 884: if(!ui_method) { ! 885: failf(data, "unable do create " OSSL_PACKAGE ! 886: " user-interface method"); ! 887: return 0; ! 888: } ! 889: UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); ! 890: UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); ! 891: UI_method_set_reader(ui_method, ssl_ui_reader); ! 892: UI_method_set_writer(ui_method, ssl_ui_writer); ! 893: /* the typecast below was added to please mingw32 */ ! 894: priv_key = (EVP_PKEY *) ! 895: ENGINE_load_private_key(data->state.engine, key_file, ! 896: ui_method, ! 897: key_passwd); ! 898: UI_destroy_method(ui_method); ! 899: if(!priv_key) { ! 900: failf(data, "failed to load private key from crypto engine"); ! 901: return 0; ! 902: } ! 903: if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { ! 904: failf(data, "unable to set private key"); ! 905: EVP_PKEY_free(priv_key); ! 906: return 0; ! 907: } ! 908: EVP_PKEY_free(priv_key); /* we don't need the handle any more... */ ! 909: } ! 910: else { ! 911: failf(data, "crypto engine not set, can't load private key"); ! 912: return 0; ! 913: } ! 914: } ! 915: break; ! 916: #else ! 917: failf(data, "file type ENG for private key not supported"); ! 918: return 0; ! 919: #endif ! 920: case SSL_FILETYPE_PKCS12: ! 921: if(!cert_done) { ! 922: failf(data, "file type P12 for private key not supported"); ! 923: return 0; ! 924: } ! 925: break; ! 926: default: ! 927: failf(data, "not supported file type for private key"); ! 928: return 0; ! 929: } ! 930: ! 931: ssl = SSL_new(ctx); ! 932: if(!ssl) { ! 933: failf(data, "unable to create an SSL structure"); ! 934: return 0; ! 935: } ! 936: ! 937: x509 = SSL_get_certificate(ssl); ! 938: ! 939: /* This version was provided by Evan Jordan and is supposed to not ! 940: leak memory as the previous version: */ ! 941: if(x509) { ! 942: EVP_PKEY *pktmp = X509_get_pubkey(x509); ! 943: EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl)); ! 944: EVP_PKEY_free(pktmp); ! 945: } ! 946: ! 947: #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL) ! 948: { ! 949: /* If RSA is used, don't check the private key if its flags indicate ! 950: * it doesn't support it. */ ! 951: EVP_PKEY *priv_key = SSL_get_privatekey(ssl); ! 952: int pktype; ! 953: #ifdef HAVE_OPAQUE_EVP_PKEY ! 954: pktype = EVP_PKEY_id(priv_key); ! 955: #else ! 956: pktype = priv_key->type; ! 957: #endif ! 958: if(pktype == EVP_PKEY_RSA) { ! 959: RSA *rsa = EVP_PKEY_get1_RSA(priv_key); ! 960: if(RSA_flags(rsa) & RSA_METHOD_FLAG_NO_CHECK) ! 961: check_privkey = FALSE; ! 962: RSA_free(rsa); /* Decrement reference count */ ! 963: } ! 964: } ! 965: #endif ! 966: ! 967: SSL_free(ssl); ! 968: ! 969: /* If we are using DSA, we can copy the parameters from ! 970: * the private key */ ! 971: ! 972: if(check_privkey == TRUE) { ! 973: /* Now we know that a key and cert have been set against ! 974: * the SSL context */ ! 975: if(!SSL_CTX_check_private_key(ctx)) { ! 976: failf(data, "Private key does not match the certificate public key"); ! 977: return 0; ! 978: } ! 979: } ! 980: } ! 981: return 1; ! 982: } ! 983: ! 984: /* returns non-zero on failure */ ! 985: static int x509_name_oneline(X509_NAME *a, char *buf, size_t size) ! 986: { ! 987: #if 0 ! 988: return X509_NAME_oneline(a, buf, size); ! 989: #else ! 990: BIO *bio_out = BIO_new(BIO_s_mem()); ! 991: BUF_MEM *biomem; ! 992: int rc; ! 993: ! 994: if(!bio_out) ! 995: return 1; /* alloc failed! */ ! 996: ! 997: rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC); ! 998: BIO_get_mem_ptr(bio_out, &biomem); ! 999: ! 1000: if((size_t)biomem->length < size) ! 1001: size = biomem->length; ! 1002: else ! 1003: size--; /* don't overwrite the buffer end */ ! 1004: ! 1005: memcpy(buf, biomem->data, size); ! 1006: buf[size] = 0; ! 1007: ! 1008: BIO_free(bio_out); ! 1009: ! 1010: return !rc; ! 1011: #endif ! 1012: } ! 1013: ! 1014: /** ! 1015: * Global SSL init ! 1016: * ! 1017: * @retval 0 error initializing SSL ! 1018: * @retval 1 SSL initialized successfully ! 1019: */ ! 1020: static int Curl_ossl_init(void) ! 1021: { ! 1022: #ifdef ENABLE_SSLKEYLOGFILE ! 1023: char *keylog_file_name; ! 1024: #endif ! 1025: ! 1026: OPENSSL_load_builtin_modules(); ! 1027: ! 1028: #ifdef USE_OPENSSL_ENGINE ! 1029: ENGINE_load_builtin_engines(); ! 1030: #endif ! 1031: ! 1032: /* CONF_MFLAGS_DEFAULT_SECTION was introduced some time between 0.9.8b and ! 1033: 0.9.8e */ ! 1034: #ifndef CONF_MFLAGS_DEFAULT_SECTION ! 1035: #define CONF_MFLAGS_DEFAULT_SECTION 0x0 ! 1036: #endif ! 1037: ! 1038: #ifndef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG ! 1039: CONF_modules_load_file(NULL, NULL, ! 1040: CONF_MFLAGS_DEFAULT_SECTION| ! 1041: CONF_MFLAGS_IGNORE_MISSING_FILE); ! 1042: #endif ! 1043: ! 1044: #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ ! 1045: !defined(LIBRESSL_VERSION_NUMBER) ! 1046: /* OpenSSL 1.1.0+ takes care of initialization itself */ ! 1047: #else ! 1048: /* Lets get nice error messages */ ! 1049: SSL_load_error_strings(); ! 1050: ! 1051: /* Init the global ciphers and digests */ ! 1052: if(!SSLeay_add_ssl_algorithms()) ! 1053: return 0; ! 1054: ! 1055: OpenSSL_add_all_algorithms(); ! 1056: #endif ! 1057: ! 1058: #ifdef ENABLE_SSLKEYLOGFILE ! 1059: if(!keylog_file_fp) { ! 1060: keylog_file_name = curl_getenv("SSLKEYLOGFILE"); ! 1061: if(keylog_file_name) { ! 1062: keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT); ! 1063: if(keylog_file_fp) { ! 1064: #ifdef WIN32 ! 1065: if(setvbuf(keylog_file_fp, NULL, _IONBF, 0)) ! 1066: #else ! 1067: if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) ! 1068: #endif ! 1069: { ! 1070: fclose(keylog_file_fp); ! 1071: keylog_file_fp = NULL; ! 1072: } ! 1073: } ! 1074: Curl_safefree(keylog_file_name); ! 1075: } ! 1076: } ! 1077: #endif ! 1078: ! 1079: /* Initialize the extra data indexes */ ! 1080: if(ossl_get_ssl_conn_index() < 0 || ossl_get_ssl_sockindex_index() < 0) ! 1081: return 0; ! 1082: ! 1083: return 1; ! 1084: } ! 1085: ! 1086: /* Global cleanup */ ! 1087: static void Curl_ossl_cleanup(void) ! 1088: { ! 1089: #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ ! 1090: !defined(LIBRESSL_VERSION_NUMBER) ! 1091: /* OpenSSL 1.1 deprecates all these cleanup functions and ! 1092: turns them into no-ops in OpenSSL 1.0 compatibility mode */ ! 1093: #else ! 1094: /* Free ciphers and digests lists */ ! 1095: EVP_cleanup(); ! 1096: ! 1097: #ifdef USE_OPENSSL_ENGINE ! 1098: /* Free engine list */ ! 1099: ENGINE_cleanup(); ! 1100: #endif ! 1101: ! 1102: /* Free OpenSSL error strings */ ! 1103: ERR_free_strings(); ! 1104: ! 1105: /* Free thread local error state, destroying hash upon zero refcount */ ! 1106: #ifdef HAVE_ERR_REMOVE_THREAD_STATE ! 1107: ERR_remove_thread_state(NULL); ! 1108: #else ! 1109: ERR_remove_state(0); ! 1110: #endif ! 1111: ! 1112: /* Free all memory allocated by all configuration modules */ ! 1113: CONF_modules_free(); ! 1114: ! 1115: #ifdef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS ! 1116: SSL_COMP_free_compression_methods(); ! 1117: #endif ! 1118: #endif ! 1119: ! 1120: #ifdef ENABLE_SSLKEYLOGFILE ! 1121: if(keylog_file_fp) { ! 1122: fclose(keylog_file_fp); ! 1123: keylog_file_fp = NULL; ! 1124: } ! 1125: #endif ! 1126: } ! 1127: ! 1128: /* ! 1129: * This function is used to determine connection status. ! 1130: * ! 1131: * Return codes: ! 1132: * 1 means the connection is still in place ! 1133: * 0 means the connection has been closed ! 1134: * -1 means the connection status is unknown ! 1135: */ ! 1136: static int Curl_ossl_check_cxn(struct connectdata *conn) ! 1137: { ! 1138: /* SSL_peek takes data out of the raw recv buffer without peeking so we use ! 1139: recv MSG_PEEK instead. Bug #795 */ ! 1140: #ifdef MSG_PEEK ! 1141: char buf; ! 1142: ssize_t nread; ! 1143: nread = recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf, ! 1144: (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK); ! 1145: if(nread == 0) ! 1146: return 0; /* connection has been closed */ ! 1147: if(nread == 1) ! 1148: return 1; /* connection still in place */ ! 1149: else if(nread == -1) { ! 1150: int err = SOCKERRNO; ! 1151: if(err == EINPROGRESS || ! 1152: #if defined(EAGAIN) && (EAGAIN != EWOULDBLOCK) ! 1153: err == EAGAIN || ! 1154: #endif ! 1155: err == EWOULDBLOCK) ! 1156: return 1; /* connection still in place */ ! 1157: if(err == ECONNRESET || ! 1158: #ifdef ECONNABORTED ! 1159: err == ECONNABORTED || ! 1160: #endif ! 1161: #ifdef ENETDOWN ! 1162: err == ENETDOWN || ! 1163: #endif ! 1164: #ifdef ENETRESET ! 1165: err == ENETRESET || ! 1166: #endif ! 1167: #ifdef ESHUTDOWN ! 1168: err == ESHUTDOWN || ! 1169: #endif ! 1170: #ifdef ETIMEDOUT ! 1171: err == ETIMEDOUT || ! 1172: #endif ! 1173: err == ENOTCONN) ! 1174: return 0; /* connection has been closed */ ! 1175: } ! 1176: #endif ! 1177: return -1; /* connection status unknown */ ! 1178: } ! 1179: ! 1180: /* Selects an OpenSSL crypto engine ! 1181: */ ! 1182: static CURLcode Curl_ossl_set_engine(struct Curl_easy *data, ! 1183: const char *engine) ! 1184: { ! 1185: #ifdef USE_OPENSSL_ENGINE ! 1186: ENGINE *e; ! 1187: ! 1188: #if OPENSSL_VERSION_NUMBER >= 0x00909000L ! 1189: e = ENGINE_by_id(engine); ! 1190: #else ! 1191: /* avoid memory leak */ ! 1192: for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) { ! 1193: const char *e_id = ENGINE_get_id(e); ! 1194: if(!strcmp(engine, e_id)) ! 1195: break; ! 1196: } ! 1197: #endif ! 1198: ! 1199: if(!e) { ! 1200: failf(data, "SSL Engine '%s' not found", engine); ! 1201: return CURLE_SSL_ENGINE_NOTFOUND; ! 1202: } ! 1203: ! 1204: if(data->state.engine) { ! 1205: ENGINE_finish(data->state.engine); ! 1206: ENGINE_free(data->state.engine); ! 1207: data->state.engine = NULL; ! 1208: } ! 1209: if(!ENGINE_init(e)) { ! 1210: char buf[256]; ! 1211: ! 1212: ENGINE_free(e); ! 1213: failf(data, "Failed to initialise SSL Engine '%s':\n%s", ! 1214: engine, ossl_strerror(ERR_get_error(), buf, sizeof(buf))); ! 1215: return CURLE_SSL_ENGINE_INITFAILED; ! 1216: } ! 1217: data->state.engine = e; ! 1218: return CURLE_OK; ! 1219: #else ! 1220: (void)engine; ! 1221: failf(data, "SSL Engine not supported"); ! 1222: return CURLE_SSL_ENGINE_NOTFOUND; ! 1223: #endif ! 1224: } ! 1225: ! 1226: /* Sets engine as default for all SSL operations ! 1227: */ ! 1228: static CURLcode Curl_ossl_set_engine_default(struct Curl_easy *data) ! 1229: { ! 1230: #ifdef USE_OPENSSL_ENGINE ! 1231: if(data->state.engine) { ! 1232: if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) { ! 1233: infof(data, "set default crypto engine '%s'\n", ! 1234: ENGINE_get_id(data->state.engine)); ! 1235: } ! 1236: else { ! 1237: failf(data, "set default crypto engine '%s' failed", ! 1238: ENGINE_get_id(data->state.engine)); ! 1239: return CURLE_SSL_ENGINE_SETFAILED; ! 1240: } ! 1241: } ! 1242: #else ! 1243: (void) data; ! 1244: #endif ! 1245: return CURLE_OK; ! 1246: } ! 1247: ! 1248: /* Return list of OpenSSL crypto engine names. ! 1249: */ ! 1250: static struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data) ! 1251: { ! 1252: struct curl_slist *list = NULL; ! 1253: #ifdef USE_OPENSSL_ENGINE ! 1254: struct curl_slist *beg; ! 1255: ENGINE *e; ! 1256: ! 1257: for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) { ! 1258: beg = curl_slist_append(list, ENGINE_get_id(e)); ! 1259: if(!beg) { ! 1260: curl_slist_free_all(list); ! 1261: return NULL; ! 1262: } ! 1263: list = beg; ! 1264: } ! 1265: #endif ! 1266: (void) data; ! 1267: return list; ! 1268: } ! 1269: ! 1270: static void ossl_close(struct ssl_connect_data *connssl) ! 1271: { ! 1272: struct ssl_backend_data *backend = connssl->backend; ! 1273: if(backend->handle) { ! 1274: (void)SSL_shutdown(backend->handle); ! 1275: SSL_set_connect_state(backend->handle); ! 1276: ! 1277: SSL_free(backend->handle); ! 1278: backend->handle = NULL; ! 1279: } ! 1280: if(backend->ctx) { ! 1281: SSL_CTX_free(backend->ctx); ! 1282: backend->ctx = NULL; ! 1283: } ! 1284: } ! 1285: ! 1286: /* ! 1287: * This function is called when an SSL connection is closed. ! 1288: */ ! 1289: static void Curl_ossl_close(struct connectdata *conn, int sockindex) ! 1290: { ! 1291: ossl_close(&conn->ssl[sockindex]); ! 1292: ossl_close(&conn->proxy_ssl[sockindex]); ! 1293: } ! 1294: ! 1295: /* ! 1296: * This function is called to shut down the SSL layer but keep the ! 1297: * socket open (CCC - Clear Command Channel) ! 1298: */ ! 1299: static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) ! 1300: { ! 1301: int retval = 0; ! 1302: struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ! 1303: struct Curl_easy *data = conn->data; ! 1304: char buf[256]; /* We will use this for the OpenSSL error buffer, so it has ! 1305: to be at least 256 bytes long. */ ! 1306: unsigned long sslerror; ! 1307: ssize_t nread; ! 1308: int buffsize; ! 1309: int err; ! 1310: bool done = FALSE; ! 1311: struct ssl_backend_data *backend = connssl->backend; ! 1312: ! 1313: #ifndef CURL_DISABLE_FTP ! 1314: /* This has only been tested on the proftpd server, and the mod_tls code ! 1315: sends a close notify alert without waiting for a close notify alert in ! 1316: response. Thus we wait for a close notify alert from the server, but ! 1317: we do not send one. Let's hope other servers do the same... */ ! 1318: ! 1319: if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) ! 1320: (void)SSL_shutdown(backend->handle); ! 1321: #endif ! 1322: ! 1323: if(backend->handle) { ! 1324: buffsize = (int)sizeof(buf); ! 1325: while(!done) { ! 1326: int what = SOCKET_READABLE(conn->sock[sockindex], ! 1327: SSL_SHUTDOWN_TIMEOUT); ! 1328: if(what > 0) { ! 1329: ERR_clear_error(); ! 1330: ! 1331: /* Something to read, let's do it and hope that it is the close ! 1332: notify alert from the server */ ! 1333: nread = (ssize_t)SSL_read(backend->handle, buf, buffsize); ! 1334: err = SSL_get_error(backend->handle, (int)nread); ! 1335: ! 1336: switch(err) { ! 1337: case SSL_ERROR_NONE: /* this is not an error */ ! 1338: case SSL_ERROR_ZERO_RETURN: /* no more data */ ! 1339: /* This is the expected response. There was no data but only ! 1340: the close notify alert */ ! 1341: done = TRUE; ! 1342: break; ! 1343: case SSL_ERROR_WANT_READ: ! 1344: /* there's data pending, re-invoke SSL_read() */ ! 1345: infof(data, "SSL_ERROR_WANT_READ\n"); ! 1346: break; ! 1347: case SSL_ERROR_WANT_WRITE: ! 1348: /* SSL wants a write. Really odd. Let's bail out. */ ! 1349: infof(data, "SSL_ERROR_WANT_WRITE\n"); ! 1350: done = TRUE; ! 1351: break; ! 1352: default: ! 1353: /* openssl/ssl.h says "look at error stack/return value/errno" */ ! 1354: sslerror = ERR_get_error(); ! 1355: failf(conn->data, OSSL_PACKAGE " SSL_read on shutdown: %s, errno %d", ! 1356: (sslerror ? ! 1357: ossl_strerror(sslerror, buf, sizeof(buf)) : ! 1358: SSL_ERROR_to_str(err)), ! 1359: SOCKERRNO); ! 1360: done = TRUE; ! 1361: break; ! 1362: } ! 1363: } ! 1364: else if(0 == what) { ! 1365: /* timeout */ ! 1366: failf(data, "SSL shutdown timeout"); ! 1367: done = TRUE; ! 1368: } ! 1369: else { ! 1370: /* anything that gets here is fatally bad */ ! 1371: failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); ! 1372: retval = -1; ! 1373: done = TRUE; ! 1374: } ! 1375: } /* while()-loop for the select() */ ! 1376: ! 1377: if(data->set.verbose) { ! 1378: #ifdef HAVE_SSL_GET_SHUTDOWN ! 1379: switch(SSL_get_shutdown(backend->handle)) { ! 1380: case SSL_SENT_SHUTDOWN: ! 1381: infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n"); ! 1382: break; ! 1383: case SSL_RECEIVED_SHUTDOWN: ! 1384: infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n"); ! 1385: break; ! 1386: case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN: ! 1387: infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|" ! 1388: "SSL_RECEIVED__SHUTDOWN\n"); ! 1389: break; ! 1390: } ! 1391: #endif ! 1392: } ! 1393: ! 1394: SSL_free(backend->handle); ! 1395: backend->handle = NULL; ! 1396: } ! 1397: return retval; ! 1398: } ! 1399: ! 1400: static void Curl_ossl_session_free(void *ptr) ! 1401: { ! 1402: /* free the ID */ ! 1403: SSL_SESSION_free(ptr); ! 1404: } ! 1405: ! 1406: /* ! 1407: * This function is called when the 'data' struct is going away. Close ! 1408: * down everything and free all resources! ! 1409: */ ! 1410: static void Curl_ossl_close_all(struct Curl_easy *data) ! 1411: { ! 1412: #ifdef USE_OPENSSL_ENGINE ! 1413: if(data->state.engine) { ! 1414: ENGINE_finish(data->state.engine); ! 1415: ENGINE_free(data->state.engine); ! 1416: data->state.engine = NULL; ! 1417: } ! 1418: #else ! 1419: (void)data; ! 1420: #endif ! 1421: #if !defined(HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED) && \ ! 1422: defined(HAVE_ERR_REMOVE_THREAD_STATE) ! 1423: /* OpenSSL 1.0.1 and 1.0.2 build an error queue that is stored per-thread ! 1424: so we need to clean it here in case the thread will be killed. All OpenSSL ! 1425: code should extract the error in association with the error so clearing ! 1426: this queue here should be harmless at worst. */ ! 1427: ERR_remove_thread_state(NULL); ! 1428: #endif ! 1429: } ! 1430: ! 1431: /* ====================================================== */ ! 1432: ! 1433: /* ! 1434: * Match subjectAltName against the host name. This requires a conversion ! 1435: * in CURL_DOES_CONVERSIONS builds. ! 1436: */ ! 1437: static bool subj_alt_hostcheck(struct Curl_easy *data, ! 1438: const char *match_pattern, const char *hostname, ! 1439: const char *dispname) ! 1440: #ifdef CURL_DOES_CONVERSIONS ! 1441: { ! 1442: bool res = FALSE; ! 1443: ! 1444: /* Curl_cert_hostcheck uses host encoding, but we get ASCII from ! 1445: OpenSSl. ! 1446: */ ! 1447: char *match_pattern2 = strdup(match_pattern); ! 1448: ! 1449: if(match_pattern2) { ! 1450: if(Curl_convert_from_network(data, match_pattern2, ! 1451: strlen(match_pattern2)) == CURLE_OK) { ! 1452: if(Curl_cert_hostcheck(match_pattern2, hostname)) { ! 1453: res = TRUE; ! 1454: infof(data, ! 1455: " subjectAltName: host \"%s\" matched cert's \"%s\"\n", ! 1456: dispname, match_pattern2); ! 1457: } ! 1458: } ! 1459: free(match_pattern2); ! 1460: } ! 1461: else { ! 1462: failf(data, ! 1463: "SSL: out of memory when allocating temporary for subjectAltName"); ! 1464: } ! 1465: return res; ! 1466: } ! 1467: #else ! 1468: { ! 1469: #ifdef CURL_DISABLE_VERBOSE_STRINGS ! 1470: (void)dispname; ! 1471: (void)data; ! 1472: #endif ! 1473: if(Curl_cert_hostcheck(match_pattern, hostname)) { ! 1474: infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"\n", ! 1475: dispname, match_pattern); ! 1476: return TRUE; ! 1477: } ! 1478: return FALSE; ! 1479: } ! 1480: #endif ! 1481: ! 1482: ! 1483: /* Quote from RFC2818 section 3.1 "Server Identity" ! 1484: ! 1485: If a subjectAltName extension of type dNSName is present, that MUST ! 1486: be used as the identity. Otherwise, the (most specific) Common Name ! 1487: field in the Subject field of the certificate MUST be used. Although ! 1488: the use of the Common Name is existing practice, it is deprecated and ! 1489: Certification Authorities are encouraged to use the dNSName instead. ! 1490: ! 1491: Matching is performed using the matching rules specified by ! 1492: [RFC2459]. If more than one identity of a given type is present in ! 1493: the certificate (e.g., more than one dNSName name, a match in any one ! 1494: of the set is considered acceptable.) Names may contain the wildcard ! 1495: character * which is considered to match any single domain name ! 1496: component or component fragment. E.g., *.a.com matches foo.a.com but ! 1497: not bar.foo.a.com. f*.com matches foo.com but not bar.com. ! 1498: ! 1499: In some cases, the URI is specified as an IP address rather than a ! 1500: hostname. In this case, the iPAddress subjectAltName must be present ! 1501: in the certificate and must exactly match the IP in the URI. ! 1502: ! 1503: */ ! 1504: static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) ! 1505: { ! 1506: bool matched = FALSE; ! 1507: int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */ ! 1508: size_t addrlen = 0; ! 1509: struct Curl_easy *data = conn->data; ! 1510: STACK_OF(GENERAL_NAME) *altnames; ! 1511: #ifdef ENABLE_IPV6 ! 1512: struct in6_addr addr; ! 1513: #else ! 1514: struct in_addr addr; ! 1515: #endif ! 1516: CURLcode result = CURLE_OK; ! 1517: bool dNSName = FALSE; /* if a dNSName field exists in the cert */ ! 1518: bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */ ! 1519: const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : ! 1520: conn->host.name; ! 1521: const char * const dispname = SSL_IS_PROXY() ? ! 1522: conn->http_proxy.host.dispname : conn->host.dispname; ! 1523: ! 1524: #ifdef ENABLE_IPV6 ! 1525: if(conn->bits.ipv6_ip && ! 1526: Curl_inet_pton(AF_INET6, hostname, &addr)) { ! 1527: target = GEN_IPADD; ! 1528: addrlen = sizeof(struct in6_addr); ! 1529: } ! 1530: else ! 1531: #endif ! 1532: if(Curl_inet_pton(AF_INET, hostname, &addr)) { ! 1533: target = GEN_IPADD; ! 1534: addrlen = sizeof(struct in_addr); ! 1535: } ! 1536: ! 1537: /* get a "list" of alternative names */ ! 1538: altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL); ! 1539: ! 1540: if(altnames) { ! 1541: #ifdef OPENSSL_IS_BORINGSSL ! 1542: size_t numalts; ! 1543: size_t i; ! 1544: #else ! 1545: int numalts; ! 1546: int i; ! 1547: #endif ! 1548: bool dnsmatched = FALSE; ! 1549: bool ipmatched = FALSE; ! 1550: ! 1551: /* get amount of alternatives, RFC2459 claims there MUST be at least ! 1552: one, but we don't depend on it... */ ! 1553: numalts = sk_GENERAL_NAME_num(altnames); ! 1554: ! 1555: /* loop through all alternatives - until a dnsmatch */ ! 1556: for(i = 0; (i < numalts) && !dnsmatched; i++) { ! 1557: /* get a handle to alternative name number i */ ! 1558: const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i); ! 1559: ! 1560: if(check->type == GEN_DNS) ! 1561: dNSName = TRUE; ! 1562: else if(check->type == GEN_IPADD) ! 1563: iPAddress = TRUE; ! 1564: ! 1565: /* only check alternatives of the same type the target is */ ! 1566: if(check->type == target) { ! 1567: /* get data and length */ ! 1568: const char *altptr = (char *)ASN1_STRING_get0_data(check->d.ia5); ! 1569: size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5); ! 1570: ! 1571: switch(target) { ! 1572: case GEN_DNS: /* name/pattern comparison */ ! 1573: /* The OpenSSL man page explicitly says: "In general it cannot be ! 1574: assumed that the data returned by ASN1_STRING_data() is null ! 1575: terminated or does not contain embedded nulls." But also that ! 1576: "The actual format of the data will depend on the actual string ! 1577: type itself: for example for an IA5String the data will be ASCII" ! 1578: ! 1579: It has been however verified that in 0.9.6 and 0.9.7, IA5String ! 1580: is always zero-terminated. ! 1581: */ ! 1582: if((altlen == strlen(altptr)) && ! 1583: /* if this isn't true, there was an embedded zero in the name ! 1584: string and we cannot match it. */ ! 1585: subj_alt_hostcheck(data, altptr, hostname, dispname)) { ! 1586: dnsmatched = TRUE; ! 1587: } ! 1588: break; ! 1589: ! 1590: case GEN_IPADD: /* IP address comparison */ ! 1591: /* compare alternative IP address if the data chunk is the same size ! 1592: our server IP address is */ ! 1593: if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) { ! 1594: ipmatched = TRUE; ! 1595: infof(data, ! 1596: " subjectAltName: host \"%s\" matched cert's IP address!\n", ! 1597: dispname); ! 1598: } ! 1599: break; ! 1600: } ! 1601: } ! 1602: } ! 1603: GENERAL_NAMES_free(altnames); ! 1604: ! 1605: if(dnsmatched || ipmatched) ! 1606: matched = TRUE; ! 1607: } ! 1608: ! 1609: if(matched) ! 1610: /* an alternative name matched */ ! 1611: ; ! 1612: else if(dNSName || iPAddress) { ! 1613: infof(data, " subjectAltName does not match %s\n", dispname); ! 1614: failf(data, "SSL: no alternative certificate subject name matches " ! 1615: "target host name '%s'", dispname); ! 1616: result = CURLE_PEER_FAILED_VERIFICATION; ! 1617: } ! 1618: else { ! 1619: /* we have to look to the last occurrence of a commonName in the ! 1620: distinguished one to get the most significant one. */ ! 1621: int j, i = -1; ! 1622: ! 1623: /* The following is done because of a bug in 0.9.6b */ ! 1624: ! 1625: unsigned char *nulstr = (unsigned char *)""; ! 1626: unsigned char *peer_CN = nulstr; ! 1627: ! 1628: X509_NAME *name = X509_get_subject_name(server_cert); ! 1629: if(name) ! 1630: while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0) ! 1631: i = j; ! 1632: ! 1633: /* we have the name entry and we will now convert this to a string ! 1634: that we can use for comparison. Doing this we support BMPstring, ! 1635: UTF8 etc. */ ! 1636: ! 1637: if(i >= 0) { ! 1638: ASN1_STRING *tmp = ! 1639: X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); ! 1640: ! 1641: /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input ! 1642: is already UTF-8 encoded. We check for this case and copy the raw ! 1643: string manually to avoid the problem. This code can be made ! 1644: conditional in the future when OpenSSL has been fixed. */ ! 1645: if(tmp) { ! 1646: if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) { ! 1647: j = ASN1_STRING_length(tmp); ! 1648: if(j >= 0) { ! 1649: peer_CN = OPENSSL_malloc(j + 1); ! 1650: if(peer_CN) { ! 1651: memcpy(peer_CN, ASN1_STRING_get0_data(tmp), j); ! 1652: peer_CN[j] = '\0'; ! 1653: } ! 1654: } ! 1655: } ! 1656: else /* not a UTF8 name */ ! 1657: j = ASN1_STRING_to_UTF8(&peer_CN, tmp); ! 1658: ! 1659: if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != j)) { ! 1660: /* there was a terminating zero before the end of string, this ! 1661: cannot match and we return failure! */ ! 1662: failf(data, "SSL: illegal cert name field"); ! 1663: result = CURLE_PEER_FAILED_VERIFICATION; ! 1664: } ! 1665: } ! 1666: } ! 1667: ! 1668: if(peer_CN == nulstr) ! 1669: peer_CN = NULL; ! 1670: else { ! 1671: /* convert peer_CN from UTF8 */ ! 1672: CURLcode rc = Curl_convert_from_utf8(data, (char *)peer_CN, ! 1673: strlen((char *)peer_CN)); ! 1674: /* Curl_convert_from_utf8 calls failf if unsuccessful */ ! 1675: if(rc) { ! 1676: OPENSSL_free(peer_CN); ! 1677: return rc; ! 1678: } ! 1679: } ! 1680: ! 1681: if(result) ! 1682: /* error already detected, pass through */ ! 1683: ; ! 1684: else if(!peer_CN) { ! 1685: failf(data, ! 1686: "SSL: unable to obtain common name from peer certificate"); ! 1687: result = CURLE_PEER_FAILED_VERIFICATION; ! 1688: } ! 1689: else if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) { ! 1690: failf(data, "SSL: certificate subject name '%s' does not match " ! 1691: "target host name '%s'", peer_CN, dispname); ! 1692: result = CURLE_PEER_FAILED_VERIFICATION; ! 1693: } ! 1694: else { ! 1695: infof(data, " common name: %s (matched)\n", peer_CN); ! 1696: } ! 1697: if(peer_CN) ! 1698: OPENSSL_free(peer_CN); ! 1699: } ! 1700: ! 1701: return result; ! 1702: } ! 1703: ! 1704: #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ ! 1705: !defined(OPENSSL_NO_OCSP) ! 1706: static CURLcode verifystatus(struct connectdata *conn, ! 1707: struct ssl_connect_data *connssl) ! 1708: { ! 1709: int i, ocsp_status; ! 1710: unsigned char *status; ! 1711: const unsigned char *p; ! 1712: CURLcode result = CURLE_OK; ! 1713: struct Curl_easy *data = conn->data; ! 1714: OCSP_RESPONSE *rsp = NULL; ! 1715: OCSP_BASICRESP *br = NULL; ! 1716: X509_STORE *st = NULL; ! 1717: STACK_OF(X509) *ch = NULL; ! 1718: struct ssl_backend_data *backend = connssl->backend; ! 1719: ! 1720: long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status); ! 1721: ! 1722: if(!status) { ! 1723: failf(data, "No OCSP response received"); ! 1724: result = CURLE_SSL_INVALIDCERTSTATUS; ! 1725: goto end; ! 1726: } ! 1727: p = status; ! 1728: rsp = d2i_OCSP_RESPONSE(NULL, &p, len); ! 1729: if(!rsp) { ! 1730: failf(data, "Invalid OCSP response"); ! 1731: result = CURLE_SSL_INVALIDCERTSTATUS; ! 1732: goto end; ! 1733: } ! 1734: ! 1735: ocsp_status = OCSP_response_status(rsp); ! 1736: if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { ! 1737: failf(data, "Invalid OCSP response status: %s (%d)", ! 1738: OCSP_response_status_str(ocsp_status), ocsp_status); ! 1739: result = CURLE_SSL_INVALIDCERTSTATUS; ! 1740: goto end; ! 1741: } ! 1742: ! 1743: br = OCSP_response_get1_basic(rsp); ! 1744: if(!br) { ! 1745: failf(data, "Invalid OCSP response"); ! 1746: result = CURLE_SSL_INVALIDCERTSTATUS; ! 1747: goto end; ! 1748: } ! 1749: ! 1750: ch = SSL_get_peer_cert_chain(backend->handle); ! 1751: st = SSL_CTX_get_cert_store(backend->ctx); ! 1752: ! 1753: #if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \ ! 1754: (defined(LIBRESSL_VERSION_NUMBER) && \ ! 1755: LIBRESSL_VERSION_NUMBER <= 0x2040200fL)) ! 1756: /* The authorized responder cert in the OCSP response MUST be signed by the ! 1757: peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert, ! 1758: no problem, but if it's an intermediate cert OpenSSL has a bug where it ! 1759: expects this issuer to be present in the chain embedded in the OCSP ! 1760: response. So we add it if necessary. */ ! 1761: ! 1762: /* First make sure the peer cert chain includes both a peer and an issuer, ! 1763: and the OCSP response contains a responder cert. */ ! 1764: if(sk_X509_num(ch) >= 2 && sk_X509_num(br->certs) >= 1) { ! 1765: X509 *responder = sk_X509_value(br->certs, sk_X509_num(br->certs) - 1); ! 1766: ! 1767: /* Find issuer of responder cert and add it to the OCSP response chain */ ! 1768: for(i = 0; i < sk_X509_num(ch); i++) { ! 1769: X509 *issuer = sk_X509_value(ch, i); ! 1770: if(X509_check_issued(issuer, responder) == X509_V_OK) { ! 1771: if(!OCSP_basic_add1_cert(br, issuer)) { ! 1772: failf(data, "Could not add issuer cert to OCSP response"); ! 1773: result = CURLE_SSL_INVALIDCERTSTATUS; ! 1774: goto end; ! 1775: } ! 1776: } ! 1777: } ! 1778: } ! 1779: #endif ! 1780: ! 1781: if(OCSP_basic_verify(br, ch, st, 0) <= 0) { ! 1782: failf(data, "OCSP response verification failed"); ! 1783: result = CURLE_SSL_INVALIDCERTSTATUS; ! 1784: goto end; ! 1785: } ! 1786: ! 1787: for(i = 0; i < OCSP_resp_count(br); i++) { ! 1788: int cert_status, crl_reason; ! 1789: OCSP_SINGLERESP *single = NULL; ! 1790: ! 1791: ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; ! 1792: ! 1793: single = OCSP_resp_get0(br, i); ! 1794: if(!single) ! 1795: continue; ! 1796: ! 1797: cert_status = OCSP_single_get0_status(single, &crl_reason, &rev, ! 1798: &thisupd, &nextupd); ! 1799: ! 1800: if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { ! 1801: failf(data, "OCSP response has expired"); ! 1802: result = CURLE_SSL_INVALIDCERTSTATUS; ! 1803: goto end; ! 1804: } ! 1805: ! 1806: infof(data, "SSL certificate status: %s (%d)\n", ! 1807: OCSP_cert_status_str(cert_status), cert_status); ! 1808: ! 1809: switch(cert_status) { ! 1810: case V_OCSP_CERTSTATUS_GOOD: ! 1811: break; ! 1812: ! 1813: case V_OCSP_CERTSTATUS_REVOKED: ! 1814: result = CURLE_SSL_INVALIDCERTSTATUS; ! 1815: ! 1816: failf(data, "SSL certificate revocation reason: %s (%d)", ! 1817: OCSP_crl_reason_str(crl_reason), crl_reason); ! 1818: goto end; ! 1819: ! 1820: case V_OCSP_CERTSTATUS_UNKNOWN: ! 1821: result = CURLE_SSL_INVALIDCERTSTATUS; ! 1822: goto end; ! 1823: } ! 1824: } ! 1825: ! 1826: end: ! 1827: if(br) ! 1828: OCSP_BASICRESP_free(br); ! 1829: OCSP_RESPONSE_free(rsp); ! 1830: ! 1831: return result; ! 1832: } ! 1833: #endif ! 1834: ! 1835: #endif /* USE_OPENSSL */ ! 1836: ! 1837: /* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions ! 1838: and thus this cannot be done there. */ ! 1839: #ifdef SSL_CTRL_SET_MSG_CALLBACK ! 1840: ! 1841: static const char *ssl_msg_type(int ssl_ver, int msg) ! 1842: { ! 1843: #ifdef SSL2_VERSION_MAJOR ! 1844: if(ssl_ver == SSL2_VERSION_MAJOR) { ! 1845: switch(msg) { ! 1846: case SSL2_MT_ERROR: ! 1847: return "Error"; ! 1848: case SSL2_MT_CLIENT_HELLO: ! 1849: return "Client hello"; ! 1850: case SSL2_MT_CLIENT_MASTER_KEY: ! 1851: return "Client key"; ! 1852: case SSL2_MT_CLIENT_FINISHED: ! 1853: return "Client finished"; ! 1854: case SSL2_MT_SERVER_HELLO: ! 1855: return "Server hello"; ! 1856: case SSL2_MT_SERVER_VERIFY: ! 1857: return "Server verify"; ! 1858: case SSL2_MT_SERVER_FINISHED: ! 1859: return "Server finished"; ! 1860: case SSL2_MT_REQUEST_CERTIFICATE: ! 1861: return "Request CERT"; ! 1862: case SSL2_MT_CLIENT_CERTIFICATE: ! 1863: return "Client CERT"; ! 1864: } ! 1865: } ! 1866: else ! 1867: #endif ! 1868: if(ssl_ver == SSL3_VERSION_MAJOR) { ! 1869: switch(msg) { ! 1870: case SSL3_MT_HELLO_REQUEST: ! 1871: return "Hello request"; ! 1872: case SSL3_MT_CLIENT_HELLO: ! 1873: return "Client hello"; ! 1874: case SSL3_MT_SERVER_HELLO: ! 1875: return "Server hello"; ! 1876: #ifdef SSL3_MT_NEWSESSION_TICKET ! 1877: case SSL3_MT_NEWSESSION_TICKET: ! 1878: return "Newsession Ticket"; ! 1879: #endif ! 1880: case SSL3_MT_CERTIFICATE: ! 1881: return "Certificate"; ! 1882: case SSL3_MT_SERVER_KEY_EXCHANGE: ! 1883: return "Server key exchange"; ! 1884: case SSL3_MT_CLIENT_KEY_EXCHANGE: ! 1885: return "Client key exchange"; ! 1886: case SSL3_MT_CERTIFICATE_REQUEST: ! 1887: return "Request CERT"; ! 1888: case SSL3_MT_SERVER_DONE: ! 1889: return "Server finished"; ! 1890: case SSL3_MT_CERTIFICATE_VERIFY: ! 1891: return "CERT verify"; ! 1892: case SSL3_MT_FINISHED: ! 1893: return "Finished"; ! 1894: #ifdef SSL3_MT_CERTIFICATE_STATUS ! 1895: case SSL3_MT_CERTIFICATE_STATUS: ! 1896: return "Certificate Status"; ! 1897: #endif ! 1898: #ifdef SSL3_MT_ENCRYPTED_EXTENSIONS ! 1899: case SSL3_MT_ENCRYPTED_EXTENSIONS: ! 1900: return "Encrypted Extensions"; ! 1901: #endif ! 1902: #ifdef SSL3_MT_END_OF_EARLY_DATA ! 1903: case SSL3_MT_END_OF_EARLY_DATA: ! 1904: return "End of early data"; ! 1905: #endif ! 1906: #ifdef SSL3_MT_KEY_UPDATE ! 1907: case SSL3_MT_KEY_UPDATE: ! 1908: return "Key update"; ! 1909: #endif ! 1910: #ifdef SSL3_MT_NEXT_PROTO ! 1911: case SSL3_MT_NEXT_PROTO: ! 1912: return "Next protocol"; ! 1913: #endif ! 1914: #ifdef SSL3_MT_MESSAGE_HASH ! 1915: case SSL3_MT_MESSAGE_HASH: ! 1916: return "Message hash"; ! 1917: #endif ! 1918: } ! 1919: } ! 1920: return "Unknown"; ! 1921: } ! 1922: ! 1923: static const char *tls_rt_type(int type) ! 1924: { ! 1925: switch(type) { ! 1926: #ifdef SSL3_RT_HEADER ! 1927: case SSL3_RT_HEADER: ! 1928: return "TLS header"; ! 1929: #endif ! 1930: case SSL3_RT_CHANGE_CIPHER_SPEC: ! 1931: return "TLS change cipher"; ! 1932: case SSL3_RT_ALERT: ! 1933: return "TLS alert"; ! 1934: case SSL3_RT_HANDSHAKE: ! 1935: return "TLS handshake"; ! 1936: case SSL3_RT_APPLICATION_DATA: ! 1937: return "TLS app data"; ! 1938: default: ! 1939: return "TLS Unknown"; ! 1940: } ! 1941: } ! 1942: ! 1943: ! 1944: /* ! 1945: * Our callback from the SSL/TLS layers. ! 1946: */ ! 1947: static void ssl_tls_trace(int direction, int ssl_ver, int content_type, ! 1948: const void *buf, size_t len, SSL *ssl, ! 1949: void *userp) ! 1950: { ! 1951: struct Curl_easy *data; ! 1952: char unknown[32]; ! 1953: const char *verstr = NULL; ! 1954: struct connectdata *conn = userp; ! 1955: ! 1956: if(!conn || !conn->data || !conn->data->set.fdebug || ! 1957: (direction != 0 && direction != 1)) ! 1958: return; ! 1959: ! 1960: data = conn->data; ! 1961: ! 1962: switch(ssl_ver) { ! 1963: #ifdef SSL2_VERSION /* removed in recent versions */ ! 1964: case SSL2_VERSION: ! 1965: verstr = "SSLv2"; ! 1966: break; ! 1967: #endif ! 1968: #ifdef SSL3_VERSION ! 1969: case SSL3_VERSION: ! 1970: verstr = "SSLv3"; ! 1971: break; ! 1972: #endif ! 1973: case TLS1_VERSION: ! 1974: verstr = "TLSv1.0"; ! 1975: break; ! 1976: #ifdef TLS1_1_VERSION ! 1977: case TLS1_1_VERSION: ! 1978: verstr = "TLSv1.1"; ! 1979: break; ! 1980: #endif ! 1981: #ifdef TLS1_2_VERSION ! 1982: case TLS1_2_VERSION: ! 1983: verstr = "TLSv1.2"; ! 1984: break; ! 1985: #endif ! 1986: #ifdef TLS1_3_VERSION ! 1987: case TLS1_3_VERSION: ! 1988: verstr = "TLSv1.3"; ! 1989: break; ! 1990: #endif ! 1991: case 0: ! 1992: break; ! 1993: default: ! 1994: msnprintf(unknown, sizeof(unknown), "(%x)", ssl_ver); ! 1995: verstr = unknown; ! 1996: break; ! 1997: } ! 1998: ! 1999: /* Log progress for interesting records only (like Handshake or Alert), skip ! 2000: * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0). ! 2001: * For TLS 1.3, skip notification of the decrypted inner Content Type. ! 2002: */ ! 2003: if(ssl_ver ! 2004: #ifdef SSL3_RT_INNER_CONTENT_TYPE ! 2005: && content_type != SSL3_RT_INNER_CONTENT_TYPE ! 2006: #endif ! 2007: ) { ! 2008: const char *msg_name, *tls_rt_name; ! 2009: char ssl_buf[1024]; ! 2010: int msg_type, txt_len; ! 2011: ! 2012: /* the info given when the version is zero is not that useful for us */ ! 2013: ! 2014: ssl_ver >>= 8; /* check the upper 8 bits only below */ ! 2015: ! 2016: /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL ! 2017: * always pass-up content-type as 0. But the interesting message-type ! 2018: * is at 'buf[0]'. ! 2019: */ ! 2020: if(ssl_ver == SSL3_VERSION_MAJOR && content_type) ! 2021: tls_rt_name = tls_rt_type(content_type); ! 2022: else ! 2023: tls_rt_name = ""; ! 2024: ! 2025: if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) { ! 2026: msg_type = *(char *)buf; ! 2027: msg_name = "Change cipher spec"; ! 2028: } ! 2029: else if(content_type == SSL3_RT_ALERT) { ! 2030: msg_type = (((char *)buf)[0] << 8) + ((char *)buf)[1]; ! 2031: msg_name = SSL_alert_desc_string_long(msg_type); ! 2032: } ! 2033: else { ! 2034: msg_type = *(char *)buf; ! 2035: msg_name = ssl_msg_type(ssl_ver, msg_type); ! 2036: } ! 2037: ! 2038: txt_len = msnprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n", ! 2039: verstr, direction?"OUT":"IN", ! 2040: tls_rt_name, msg_name, msg_type); ! 2041: if(0 <= txt_len && (unsigned)txt_len < sizeof(ssl_buf)) { ! 2042: Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len); ! 2043: } ! 2044: } ! 2045: ! 2046: Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT : ! 2047: CURLINFO_SSL_DATA_IN, (char *)buf, len); ! 2048: (void) ssl; ! 2049: } ! 2050: #endif ! 2051: ! 2052: #ifdef USE_OPENSSL ! 2053: /* ====================================================== */ ! 2054: ! 2055: #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME ! 2056: # define use_sni(x) sni = (x) ! 2057: #else ! 2058: # define use_sni(x) Curl_nop_stmt ! 2059: #endif ! 2060: ! 2061: /* Check for OpenSSL 1.0.2 which has ALPN support. */ ! 2062: #undef HAS_ALPN ! 2063: #if OPENSSL_VERSION_NUMBER >= 0x10002000L \ ! 2064: && !defined(OPENSSL_NO_TLSEXT) ! 2065: # define HAS_ALPN 1 ! 2066: #endif ! 2067: ! 2068: /* Check for OpenSSL 1.0.1 which has NPN support. */ ! 2069: #undef HAS_NPN ! 2070: #if OPENSSL_VERSION_NUMBER >= 0x10001000L \ ! 2071: && !defined(OPENSSL_NO_TLSEXT) \ ! 2072: && !defined(OPENSSL_NO_NEXTPROTONEG) ! 2073: # define HAS_NPN 1 ! 2074: #endif ! 2075: ! 2076: #ifdef HAS_NPN ! 2077: ! 2078: /* ! 2079: * in is a list of length prefixed strings. this function has to select ! 2080: * the protocol we want to use from the list and write its string into out. ! 2081: */ ! 2082: ! 2083: static int ! 2084: select_next_protocol(unsigned char **out, unsigned char *outlen, ! 2085: const unsigned char *in, unsigned int inlen, ! 2086: const char *key, unsigned int keylen) ! 2087: { ! 2088: unsigned int i; ! 2089: for(i = 0; i + keylen <= inlen; i += in[i] + 1) { ! 2090: if(memcmp(&in[i + 1], key, keylen) == 0) { ! 2091: *out = (unsigned char *) &in[i + 1]; ! 2092: *outlen = in[i]; ! 2093: return 0; ! 2094: } ! 2095: } ! 2096: return -1; ! 2097: } ! 2098: ! 2099: static int ! 2100: select_next_proto_cb(SSL *ssl, ! 2101: unsigned char **out, unsigned char *outlen, ! 2102: const unsigned char *in, unsigned int inlen, ! 2103: void *arg) ! 2104: { ! 2105: struct connectdata *conn = (struct connectdata*) arg; ! 2106: ! 2107: (void)ssl; ! 2108: ! 2109: #ifdef USE_NGHTTP2 ! 2110: if(conn->data->set.httpversion >= CURL_HTTP_VERSION_2 && ! 2111: !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID, ! 2112: NGHTTP2_PROTO_VERSION_ID_LEN)) { ! 2113: infof(conn->data, "NPN, negotiated HTTP2 (%s)\n", ! 2114: NGHTTP2_PROTO_VERSION_ID); ! 2115: conn->negnpn = CURL_HTTP_VERSION_2; ! 2116: return SSL_TLSEXT_ERR_OK; ! 2117: } ! 2118: #endif ! 2119: ! 2120: if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1, ! 2121: ALPN_HTTP_1_1_LENGTH)) { ! 2122: infof(conn->data, "NPN, negotiated HTTP1.1\n"); ! 2123: conn->negnpn = CURL_HTTP_VERSION_1_1; ! 2124: return SSL_TLSEXT_ERR_OK; ! 2125: } ! 2126: ! 2127: infof(conn->data, "NPN, no overlap, use HTTP1.1\n"); ! 2128: *out = (unsigned char *)ALPN_HTTP_1_1; ! 2129: *outlen = ALPN_HTTP_1_1_LENGTH; ! 2130: conn->negnpn = CURL_HTTP_VERSION_1_1; ! 2131: ! 2132: return SSL_TLSEXT_ERR_OK; ! 2133: } ! 2134: #endif /* HAS_NPN */ ! 2135: ! 2136: #ifndef CURL_DISABLE_VERBOSE_STRINGS ! 2137: static const char * ! 2138: get_ssl_version_txt(SSL *ssl) ! 2139: { ! 2140: if(!ssl) ! 2141: return ""; ! 2142: ! 2143: switch(SSL_version(ssl)) { ! 2144: #ifdef TLS1_3_VERSION ! 2145: case TLS1_3_VERSION: ! 2146: return "TLSv1.3"; ! 2147: #endif ! 2148: #if OPENSSL_VERSION_NUMBER >= 0x1000100FL ! 2149: case TLS1_2_VERSION: ! 2150: return "TLSv1.2"; ! 2151: case TLS1_1_VERSION: ! 2152: return "TLSv1.1"; ! 2153: #endif ! 2154: case TLS1_VERSION: ! 2155: return "TLSv1.0"; ! 2156: case SSL3_VERSION: ! 2157: return "SSLv3"; ! 2158: case SSL2_VERSION: ! 2159: return "SSLv2"; ! 2160: } ! 2161: return "unknown"; ! 2162: } ! 2163: #endif ! 2164: ! 2165: #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ ! 2166: static CURLcode ! 2167: set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn) ! 2168: { ! 2169: /* first, TLS min version... */ ! 2170: long curl_ssl_version_min = SSL_CONN_CONFIG(version); ! 2171: long curl_ssl_version_max; ! 2172: ! 2173: /* convert cURL min SSL version option to OpenSSL constant */ ! 2174: #if defined(OPENSSL_IS_BORINGSSL) || defined(LIBRESSL_VERSION_NUMBER) ! 2175: uint16_t ossl_ssl_version_min = 0; ! 2176: uint16_t ossl_ssl_version_max = 0; ! 2177: #else ! 2178: long ossl_ssl_version_min = 0; ! 2179: long ossl_ssl_version_max = 0; ! 2180: #endif ! 2181: switch(curl_ssl_version_min) { ! 2182: case CURL_SSLVERSION_TLSv1: /* TLS 1.x */ ! 2183: case CURL_SSLVERSION_TLSv1_0: ! 2184: ossl_ssl_version_min = TLS1_VERSION; ! 2185: break; ! 2186: case CURL_SSLVERSION_TLSv1_1: ! 2187: ossl_ssl_version_min = TLS1_1_VERSION; ! 2188: break; ! 2189: case CURL_SSLVERSION_TLSv1_2: ! 2190: ossl_ssl_version_min = TLS1_2_VERSION; ! 2191: break; ! 2192: #ifdef TLS1_3_VERSION ! 2193: case CURL_SSLVERSION_TLSv1_3: ! 2194: ossl_ssl_version_min = TLS1_3_VERSION; ! 2195: break; ! 2196: #endif ! 2197: } ! 2198: ! 2199: /* CURL_SSLVERSION_DEFAULT means that no option was selected. ! 2200: We don't want to pass 0 to SSL_CTX_set_min_proto_version as ! 2201: it would enable all versions down to the lowest supported by ! 2202: the library. ! 2203: So we skip this, and stay with the OS default ! 2204: */ ! 2205: if(curl_ssl_version_min != CURL_SSLVERSION_DEFAULT) { ! 2206: if(!SSL_CTX_set_min_proto_version(ctx, ossl_ssl_version_min)) { ! 2207: return CURLE_SSL_CONNECT_ERROR; ! 2208: } ! 2209: } ! 2210: ! 2211: /* ... then, TLS max version */ ! 2212: curl_ssl_version_max = SSL_CONN_CONFIG(version_max); ! 2213: ! 2214: /* convert cURL max SSL version option to OpenSSL constant */ ! 2215: switch(curl_ssl_version_max) { ! 2216: case CURL_SSLVERSION_MAX_TLSv1_0: ! 2217: ossl_ssl_version_max = TLS1_VERSION; ! 2218: break; ! 2219: case CURL_SSLVERSION_MAX_TLSv1_1: ! 2220: ossl_ssl_version_max = TLS1_1_VERSION; ! 2221: break; ! 2222: case CURL_SSLVERSION_MAX_TLSv1_2: ! 2223: ossl_ssl_version_max = TLS1_2_VERSION; ! 2224: break; ! 2225: #ifdef TLS1_3_VERSION ! 2226: case CURL_SSLVERSION_MAX_TLSv1_3: ! 2227: ossl_ssl_version_max = TLS1_3_VERSION; ! 2228: break; ! 2229: #endif ! 2230: case CURL_SSLVERSION_MAX_NONE: /* none selected */ ! 2231: case CURL_SSLVERSION_MAX_DEFAULT: /* max selected */ ! 2232: default: ! 2233: /* SSL_CTX_set_max_proto_version states that: ! 2234: setting the maximum to 0 will enable ! 2235: protocol versions up to the highest version ! 2236: supported by the library */ ! 2237: ossl_ssl_version_max = 0; ! 2238: break; ! 2239: } ! 2240: ! 2241: if(!SSL_CTX_set_max_proto_version(ctx, ossl_ssl_version_max)) { ! 2242: return CURLE_SSL_CONNECT_ERROR; ! 2243: } ! 2244: ! 2245: return CURLE_OK; ! 2246: } ! 2247: #endif ! 2248: ! 2249: #ifdef OPENSSL_IS_BORINGSSL ! 2250: typedef uint32_t ctx_option_t; ! 2251: #else ! 2252: typedef long ctx_option_t; ! 2253: #endif ! 2254: ! 2255: #if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */ ! 2256: static CURLcode ! 2257: set_ssl_version_min_max_legacy(ctx_option_t *ctx_options, ! 2258: struct connectdata *conn, int sockindex) ! 2259: { ! 2260: #if (OPENSSL_VERSION_NUMBER < 0x1000100FL) || !defined(TLS1_3_VERSION) ! 2261: /* convoluted #if condition just to avoid compiler warnings on unused ! 2262: variable */ ! 2263: struct Curl_easy *data = conn->data; ! 2264: #endif ! 2265: long ssl_version = SSL_CONN_CONFIG(version); ! 2266: long ssl_version_max = SSL_CONN_CONFIG(version_max); ! 2267: ! 2268: switch(ssl_version) { ! 2269: case CURL_SSLVERSION_TLSv1_3: ! 2270: #ifdef TLS1_3_VERSION ! 2271: { ! 2272: struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ! 2273: SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION); ! 2274: *ctx_options |= SSL_OP_NO_TLSv1_2; ! 2275: } ! 2276: #else ! 2277: (void)sockindex; ! 2278: (void)ctx_options; ! 2279: failf(data, OSSL_PACKAGE " was built without TLS 1.3 support"); ! 2280: return CURLE_NOT_BUILT_IN; ! 2281: #endif ! 2282: /* FALLTHROUGH */ ! 2283: case CURL_SSLVERSION_TLSv1_2: ! 2284: #if OPENSSL_VERSION_NUMBER >= 0x1000100FL ! 2285: *ctx_options |= SSL_OP_NO_TLSv1_1; ! 2286: #else ! 2287: failf(data, OSSL_PACKAGE " was built without TLS 1.2 support"); ! 2288: return CURLE_NOT_BUILT_IN; ! 2289: #endif ! 2290: /* FALLTHROUGH */ ! 2291: case CURL_SSLVERSION_TLSv1_1: ! 2292: #if OPENSSL_VERSION_NUMBER >= 0x1000100FL ! 2293: *ctx_options |= SSL_OP_NO_TLSv1; ! 2294: #else ! 2295: failf(data, OSSL_PACKAGE " was built without TLS 1.1 support"); ! 2296: return CURLE_NOT_BUILT_IN; ! 2297: #endif ! 2298: /* FALLTHROUGH */ ! 2299: case CURL_SSLVERSION_TLSv1_0: ! 2300: case CURL_SSLVERSION_TLSv1: ! 2301: break; ! 2302: } ! 2303: ! 2304: switch(ssl_version_max) { ! 2305: case CURL_SSLVERSION_MAX_TLSv1_0: ! 2306: #if OPENSSL_VERSION_NUMBER >= 0x1000100FL ! 2307: *ctx_options |= SSL_OP_NO_TLSv1_1; ! 2308: #endif ! 2309: /* FALLTHROUGH */ ! 2310: case CURL_SSLVERSION_MAX_TLSv1_1: ! 2311: #if OPENSSL_VERSION_NUMBER >= 0x1000100FL ! 2312: *ctx_options |= SSL_OP_NO_TLSv1_2; ! 2313: #endif ! 2314: /* FALLTHROUGH */ ! 2315: case CURL_SSLVERSION_MAX_TLSv1_2: ! 2316: #ifdef TLS1_3_VERSION ! 2317: *ctx_options |= SSL_OP_NO_TLSv1_3; ! 2318: #endif ! 2319: break; ! 2320: case CURL_SSLVERSION_MAX_TLSv1_3: ! 2321: #ifdef TLS1_3_VERSION ! 2322: break; ! 2323: #else ! 2324: failf(data, OSSL_PACKAGE " was built without TLS 1.3 support"); ! 2325: return CURLE_NOT_BUILT_IN; ! 2326: #endif ! 2327: } ! 2328: return CURLE_OK; ! 2329: } ! 2330: #endif ! 2331: ! 2332: /* The "new session" callback must return zero if the session can be removed ! 2333: * or non-zero if the session has been put into the session cache. ! 2334: */ ! 2335: static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) ! 2336: { ! 2337: int res = 0; ! 2338: struct connectdata *conn; ! 2339: struct Curl_easy *data; ! 2340: int sockindex; ! 2341: curl_socket_t *sockindex_ptr; ! 2342: int connectdata_idx = ossl_get_ssl_conn_index(); ! 2343: int sockindex_idx = ossl_get_ssl_sockindex_index(); ! 2344: ! 2345: if(connectdata_idx < 0 || sockindex_idx < 0) ! 2346: return 0; ! 2347: ! 2348: conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx); ! 2349: if(!conn) ! 2350: return 0; ! 2351: ! 2352: data = conn->data; ! 2353: ! 2354: /* The sockindex has been stored as a pointer to an array element */ ! 2355: sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx); ! 2356: sockindex = (int)(sockindex_ptr - conn->sock); ! 2357: ! 2358: if(SSL_SET_OPTION(primary.sessionid)) { ! 2359: bool incache; ! 2360: void *old_ssl_sessionid = NULL; ! 2361: ! 2362: Curl_ssl_sessionid_lock(conn); ! 2363: incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, ! 2364: sockindex)); ! 2365: if(incache) { ! 2366: if(old_ssl_sessionid != ssl_sessionid) { ! 2367: infof(data, "old SSL session ID is stale, removing\n"); ! 2368: Curl_ssl_delsessionid(conn, old_ssl_sessionid); ! 2369: incache = FALSE; ! 2370: } ! 2371: } ! 2372: ! 2373: if(!incache) { ! 2374: if(!Curl_ssl_addsessionid(conn, ssl_sessionid, ! 2375: 0 /* unknown size */, sockindex)) { ! 2376: /* the session has been put into the session cache */ ! 2377: res = 1; ! 2378: } ! 2379: else ! 2380: failf(data, "failed to store ssl session"); ! 2381: } ! 2382: Curl_ssl_sessionid_unlock(conn); ! 2383: } ! 2384: ! 2385: return res; ! 2386: } ! 2387: ! 2388: static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) ! 2389: { ! 2390: CURLcode result = CURLE_OK; ! 2391: char *ciphers; ! 2392: struct Curl_easy *data = conn->data; ! 2393: SSL_METHOD_QUAL SSL_METHOD *req_method = NULL; ! 2394: X509_LOOKUP *lookup = NULL; ! 2395: curl_socket_t sockfd = conn->sock[sockindex]; ! 2396: struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ! 2397: ctx_option_t ctx_options = 0; ! 2398: ! 2399: #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME ! 2400: bool sni; ! 2401: const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : ! 2402: conn->host.name; ! 2403: #ifdef ENABLE_IPV6 ! 2404: struct in6_addr addr; ! 2405: #else ! 2406: struct in_addr addr; ! 2407: #endif ! 2408: #endif ! 2409: long * const certverifyresult = SSL_IS_PROXY() ? ! 2410: &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; ! 2411: const long int ssl_version = SSL_CONN_CONFIG(version); ! 2412: #ifdef USE_TLS_SRP ! 2413: const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype); ! 2414: #endif ! 2415: char * const ssl_cert = SSL_SET_OPTION(cert); ! 2416: const char * const ssl_cert_type = SSL_SET_OPTION(cert_type); ! 2417: const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); ! 2418: const char * const ssl_capath = SSL_CONN_CONFIG(CApath); ! 2419: const bool verifypeer = SSL_CONN_CONFIG(verifypeer); ! 2420: const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); ! 2421: char error_buffer[256]; ! 2422: struct ssl_backend_data *backend = connssl->backend; ! 2423: ! 2424: DEBUGASSERT(ssl_connect_1 == connssl->connecting_state); ! 2425: ! 2426: /* Make funny stuff to get random input */ ! 2427: result = Curl_ossl_seed(data); ! 2428: if(result) ! 2429: return result; ! 2430: ! 2431: *certverifyresult = !X509_V_OK; ! 2432: ! 2433: /* check to see if we've been told to use an explicit SSL/TLS version */ ! 2434: ! 2435: switch(ssl_version) { ! 2436: case CURL_SSLVERSION_DEFAULT: ! 2437: case CURL_SSLVERSION_TLSv1: ! 2438: case CURL_SSLVERSION_TLSv1_0: ! 2439: case CURL_SSLVERSION_TLSv1_1: ! 2440: case CURL_SSLVERSION_TLSv1_2: ! 2441: case CURL_SSLVERSION_TLSv1_3: ! 2442: /* it will be handled later with the context options */ ! 2443: #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) ! 2444: req_method = TLS_client_method(); ! 2445: #else ! 2446: req_method = SSLv23_client_method(); ! 2447: #endif ! 2448: use_sni(TRUE); ! 2449: break; ! 2450: case CURL_SSLVERSION_SSLv2: ! 2451: #ifdef OPENSSL_NO_SSL2 ! 2452: failf(data, OSSL_PACKAGE " was built without SSLv2 support"); ! 2453: return CURLE_NOT_BUILT_IN; ! 2454: #else ! 2455: #ifdef USE_TLS_SRP ! 2456: if(ssl_authtype == CURL_TLSAUTH_SRP) ! 2457: return CURLE_SSL_CONNECT_ERROR; ! 2458: #endif ! 2459: req_method = SSLv2_client_method(); ! 2460: use_sni(FALSE); ! 2461: break; ! 2462: #endif ! 2463: case CURL_SSLVERSION_SSLv3: ! 2464: #ifdef OPENSSL_NO_SSL3_METHOD ! 2465: failf(data, OSSL_PACKAGE " was built without SSLv3 support"); ! 2466: return CURLE_NOT_BUILT_IN; ! 2467: #else ! 2468: #ifdef USE_TLS_SRP ! 2469: if(ssl_authtype == CURL_TLSAUTH_SRP) ! 2470: return CURLE_SSL_CONNECT_ERROR; ! 2471: #endif ! 2472: req_method = SSLv3_client_method(); ! 2473: use_sni(FALSE); ! 2474: break; ! 2475: #endif ! 2476: default: ! 2477: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); ! 2478: return CURLE_SSL_CONNECT_ERROR; ! 2479: } ! 2480: ! 2481: if(backend->ctx) ! 2482: SSL_CTX_free(backend->ctx); ! 2483: backend->ctx = SSL_CTX_new(req_method); ! 2484: ! 2485: if(!backend->ctx) { ! 2486: failf(data, "SSL: couldn't create a context: %s", ! 2487: ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer))); ! 2488: return CURLE_OUT_OF_MEMORY; ! 2489: } ! 2490: ! 2491: #ifdef SSL_MODE_RELEASE_BUFFERS ! 2492: SSL_CTX_set_mode(backend->ctx, SSL_MODE_RELEASE_BUFFERS); ! 2493: #endif ! 2494: ! 2495: #ifdef SSL_CTRL_SET_MSG_CALLBACK ! 2496: if(data->set.fdebug && data->set.verbose) { ! 2497: /* the SSL trace callback is only used for verbose logging */ ! 2498: SSL_CTX_set_msg_callback(backend->ctx, ssl_tls_trace); ! 2499: SSL_CTX_set_msg_callback_arg(backend->ctx, conn); ! 2500: } ! 2501: #endif ! 2502: ! 2503: /* OpenSSL contains code to work-around lots of bugs and flaws in various ! 2504: SSL-implementations. SSL_CTX_set_options() is used to enabled those ! 2505: work-arounds. The man page for this option states that SSL_OP_ALL enables ! 2506: all the work-arounds and that "It is usually safe to use SSL_OP_ALL to ! 2507: enable the bug workaround options if compatibility with somewhat broken ! 2508: implementations is desired." ! 2509: ! 2510: The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to ! 2511: disable "rfc4507bis session ticket support". rfc4507bis was later turned ! 2512: into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077 ! 2513: ! 2514: The enabled extension concerns the session management. I wonder how often ! 2515: libcurl stops a connection and then resumes a TLS session. also, sending ! 2516: the session data is some overhead. .I suggest that you just use your ! 2517: proposed patch (which explicitly disables TICKET). ! 2518: ! 2519: If someone writes an application with libcurl and openssl who wants to ! 2520: enable the feature, one can do this in the SSL callback. ! 2521: ! 2522: SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper ! 2523: interoperability with web server Netscape Enterprise Server 2.0.1 which ! 2524: was released back in 1996. ! 2525: ! 2526: Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has ! 2527: become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate ! 2528: CVE-2010-4180 when using previous OpenSSL versions we no longer enable ! 2529: this option regardless of OpenSSL version and SSL_OP_ALL definition. ! 2530: ! 2531: OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability ! 2532: (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to ! 2533: SSL_OP_ALL that _disables_ that work-around despite the fact that ! 2534: SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to ! 2535: keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit ! 2536: must not be set. ! 2537: */ ! 2538: ! 2539: ctx_options = SSL_OP_ALL; ! 2540: ! 2541: #ifdef SSL_OP_NO_TICKET ! 2542: ctx_options |= SSL_OP_NO_TICKET; ! 2543: #endif ! 2544: ! 2545: #ifdef SSL_OP_NO_COMPRESSION ! 2546: ctx_options |= SSL_OP_NO_COMPRESSION; ! 2547: #endif ! 2548: ! 2549: #ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG ! 2550: /* mitigate CVE-2010-4180 */ ! 2551: ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; ! 2552: #endif ! 2553: ! 2554: #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS ! 2555: /* unless the user explicitly ask to allow the protocol vulnerability we ! 2556: use the work-around */ ! 2557: if(!SSL_SET_OPTION(enable_beast)) ! 2558: ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; ! 2559: #endif ! 2560: ! 2561: switch(ssl_version) { ! 2562: /* "--sslv2" option means SSLv2 only, disable all others */ ! 2563: case CURL_SSLVERSION_SSLv2: ! 2564: #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ ! 2565: SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION); ! 2566: SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION); ! 2567: #else ! 2568: ctx_options |= SSL_OP_NO_SSLv3; ! 2569: ctx_options |= SSL_OP_NO_TLSv1; ! 2570: # if OPENSSL_VERSION_NUMBER >= 0x1000100FL ! 2571: ctx_options |= SSL_OP_NO_TLSv1_1; ! 2572: ctx_options |= SSL_OP_NO_TLSv1_2; ! 2573: # ifdef TLS1_3_VERSION ! 2574: ctx_options |= SSL_OP_NO_TLSv1_3; ! 2575: # endif ! 2576: # endif ! 2577: #endif ! 2578: break; ! 2579: ! 2580: /* "--sslv3" option means SSLv3 only, disable all others */ ! 2581: case CURL_SSLVERSION_SSLv3: ! 2582: #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ ! 2583: SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION); ! 2584: SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION); ! 2585: #else ! 2586: ctx_options |= SSL_OP_NO_SSLv2; ! 2587: ctx_options |= SSL_OP_NO_TLSv1; ! 2588: # if OPENSSL_VERSION_NUMBER >= 0x1000100FL ! 2589: ctx_options |= SSL_OP_NO_TLSv1_1; ! 2590: ctx_options |= SSL_OP_NO_TLSv1_2; ! 2591: # ifdef TLS1_3_VERSION ! 2592: ctx_options |= SSL_OP_NO_TLSv1_3; ! 2593: # endif ! 2594: # endif ! 2595: #endif ! 2596: break; ! 2597: ! 2598: /* "--tlsv<x.y>" options mean TLS >= version <x.y> */ ! 2599: case CURL_SSLVERSION_DEFAULT: ! 2600: case CURL_SSLVERSION_TLSv1: /* TLS >= version 1.0 */ ! 2601: case CURL_SSLVERSION_TLSv1_0: /* TLS >= version 1.0 */ ! 2602: case CURL_SSLVERSION_TLSv1_1: /* TLS >= version 1.1 */ ! 2603: case CURL_SSLVERSION_TLSv1_2: /* TLS >= version 1.2 */ ! 2604: case CURL_SSLVERSION_TLSv1_3: /* TLS >= version 1.3 */ ! 2605: /* asking for any TLS version as the minimum, means no SSL versions ! 2606: allowed */ ! 2607: ctx_options |= SSL_OP_NO_SSLv2; ! 2608: ctx_options |= SSL_OP_NO_SSLv3; ! 2609: ! 2610: #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ ! 2611: result = set_ssl_version_min_max(backend->ctx, conn); ! 2612: #else ! 2613: result = set_ssl_version_min_max_legacy(&ctx_options, conn, sockindex); ! 2614: #endif ! 2615: if(result != CURLE_OK) ! 2616: return result; ! 2617: break; ! 2618: ! 2619: default: ! 2620: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); ! 2621: return CURLE_SSL_CONNECT_ERROR; ! 2622: } ! 2623: ! 2624: SSL_CTX_set_options(backend->ctx, ctx_options); ! 2625: ! 2626: #ifdef HAS_NPN ! 2627: if(conn->bits.tls_enable_npn) ! 2628: SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, conn); ! 2629: #endif ! 2630: ! 2631: #ifdef HAS_ALPN ! 2632: if(conn->bits.tls_enable_alpn) { ! 2633: int cur = 0; ! 2634: unsigned char protocols[128]; ! 2635: ! 2636: #ifdef USE_NGHTTP2 ! 2637: if(data->set.httpversion >= CURL_HTTP_VERSION_2 && ! 2638: (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) { ! 2639: protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; ! 2640: ! 2641: memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, ! 2642: NGHTTP2_PROTO_VERSION_ID_LEN); ! 2643: cur += NGHTTP2_PROTO_VERSION_ID_LEN; ! 2644: infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); ! 2645: } ! 2646: #endif ! 2647: ! 2648: protocols[cur++] = ALPN_HTTP_1_1_LENGTH; ! 2649: memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); ! 2650: cur += ALPN_HTTP_1_1_LENGTH; ! 2651: infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); ! 2652: ! 2653: /* expects length prefixed preference ordered list of protocols in wire ! 2654: * format ! 2655: */ ! 2656: SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur); ! 2657: } ! 2658: #endif ! 2659: ! 2660: if(ssl_cert || ssl_cert_type) { ! 2661: if(!cert_stuff(conn, backend->ctx, ssl_cert, ssl_cert_type, ! 2662: SSL_SET_OPTION(key), SSL_SET_OPTION(key_type), ! 2663: SSL_SET_OPTION(key_passwd))) { ! 2664: /* failf() is already done in cert_stuff() */ ! 2665: return CURLE_SSL_CERTPROBLEM; ! 2666: } ! 2667: } ! 2668: ! 2669: ciphers = SSL_CONN_CONFIG(cipher_list); ! 2670: if(!ciphers) ! 2671: ciphers = (char *)DEFAULT_CIPHER_SELECTION; ! 2672: if(ciphers) { ! 2673: if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) { ! 2674: failf(data, "failed setting cipher list: %s", ciphers); ! 2675: return CURLE_SSL_CIPHER; ! 2676: } ! 2677: infof(data, "Cipher selection: %s\n", ciphers); ! 2678: } ! 2679: ! 2680: #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES ! 2681: { ! 2682: char *ciphers13 = SSL_CONN_CONFIG(cipher_list13); ! 2683: if(ciphers13) { ! 2684: if(!SSL_CTX_set_ciphersuites(backend->ctx, ciphers13)) { ! 2685: failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13); ! 2686: return CURLE_SSL_CIPHER; ! 2687: } ! 2688: infof(data, "TLS 1.3 cipher selection: %s\n", ciphers13); ! 2689: } ! 2690: } ! 2691: #endif ! 2692: ! 2693: #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH ! 2694: /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ ! 2695: SSL_CTX_set_post_handshake_auth(backend->ctx, 1); ! 2696: #endif ! 2697: ! 2698: #ifdef USE_TLS_SRP ! 2699: if(ssl_authtype == CURL_TLSAUTH_SRP) { ! 2700: char * const ssl_username = SSL_SET_OPTION(username); ! 2701: ! 2702: infof(data, "Using TLS-SRP username: %s\n", ssl_username); ! 2703: ! 2704: if(!SSL_CTX_set_srp_username(backend->ctx, ssl_username)) { ! 2705: failf(data, "Unable to set SRP user name"); ! 2706: return CURLE_BAD_FUNCTION_ARGUMENT; ! 2707: } ! 2708: if(!SSL_CTX_set_srp_password(backend->ctx, SSL_SET_OPTION(password))) { ! 2709: failf(data, "failed setting SRP password"); ! 2710: return CURLE_BAD_FUNCTION_ARGUMENT; ! 2711: } ! 2712: if(!SSL_CONN_CONFIG(cipher_list)) { ! 2713: infof(data, "Setting cipher list SRP\n"); ! 2714: ! 2715: if(!SSL_CTX_set_cipher_list(backend->ctx, "SRP")) { ! 2716: failf(data, "failed setting SRP cipher list"); ! 2717: return CURLE_SSL_CIPHER; ! 2718: } ! 2719: } ! 2720: } ! 2721: #endif ! 2722: ! 2723: #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) ! 2724: /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */ ! 2725: if(ssl_cafile) { ! 2726: if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) { ! 2727: if(verifypeer) { ! 2728: /* Fail if we insist on successfully verifying the server. */ ! 2729: failf(data, "error setting certificate file: %s", ssl_cafile); ! 2730: return CURLE_SSL_CACERT_BADFILE; ! 2731: } ! 2732: /* Continue with a warning if no certificate verification is required. */ ! 2733: infof(data, "error setting certificate file, continuing anyway\n"); ! 2734: } ! 2735: infof(data, " CAfile: %s\n", ssl_cafile); ! 2736: } ! 2737: if(ssl_capath) { ! 2738: if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) { ! 2739: if(verifypeer) { ! 2740: /* Fail if we insist on successfully verifying the server. */ ! 2741: failf(data, "error setting certificate path: %s", ssl_capath); ! 2742: return CURLE_SSL_CACERT_BADFILE; ! 2743: } ! 2744: /* Continue with a warning if no certificate verification is required. */ ! 2745: infof(data, "error setting certificate path, continuing anyway\n"); ! 2746: } ! 2747: infof(data, " CApath: %s\n", ssl_capath); ! 2748: } ! 2749: #else ! 2750: if(ssl_cafile || ssl_capath) { ! 2751: /* tell SSL where to find CA certificates that are used to verify ! 2752: the servers certificate. */ ! 2753: if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) { ! 2754: if(verifypeer) { ! 2755: /* Fail if we insist on successfully verifying the server. */ ! 2756: failf(data, "error setting certificate verify locations:\n" ! 2757: " CAfile: %s\n CApath: %s", ! 2758: ssl_cafile ? ssl_cafile : "none", ! 2759: ssl_capath ? ssl_capath : "none"); ! 2760: return CURLE_SSL_CACERT_BADFILE; ! 2761: } ! 2762: /* Just continue with a warning if no strict certificate verification ! 2763: is required. */ ! 2764: infof(data, "error setting certificate verify locations," ! 2765: " continuing anyway:\n"); ! 2766: } ! 2767: else { ! 2768: /* Everything is fine. */ ! 2769: infof(data, "successfully set certificate verify locations:\n"); ! 2770: } ! 2771: infof(data, ! 2772: " CAfile: %s\n" ! 2773: " CApath: %s\n", ! 2774: ssl_cafile ? ssl_cafile : "none", ! 2775: ssl_capath ? ssl_capath : "none"); ! 2776: } ! 2777: #endif ! 2778: ! 2779: #ifdef CURL_CA_FALLBACK ! 2780: else if(verifypeer) { ! 2781: /* verifying the peer without any CA certificates won't ! 2782: work so use openssl's built in default as fallback */ ! 2783: SSL_CTX_set_default_verify_paths(backend->ctx); ! 2784: } ! 2785: #endif ! 2786: ! 2787: if(ssl_crlfile) { ! 2788: /* tell SSL where to find CRL file that is used to check certificate ! 2789: * revocation */ ! 2790: lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(backend->ctx), ! 2791: X509_LOOKUP_file()); ! 2792: if(!lookup || ! 2793: (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) { ! 2794: failf(data, "error loading CRL file: %s", ssl_crlfile); ! 2795: return CURLE_SSL_CRL_BADFILE; ! 2796: } ! 2797: /* Everything is fine. */ ! 2798: infof(data, "successfully load CRL file:\n"); ! 2799: X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), ! 2800: X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); ! 2801: ! 2802: infof(data, " CRLfile: %s\n", ssl_crlfile); ! 2803: } ! 2804: ! 2805: if(verifypeer) { ! 2806: /* Try building a chain using issuers in the trusted store first to avoid ! 2807: problems with server-sent legacy intermediates. Newer versions of ! 2808: OpenSSL do alternate chain checking by default which gives us the same ! 2809: fix without as much of a performance hit (slight), so we prefer that if ! 2810: available. ! 2811: https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest ! 2812: */ ! 2813: #if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) ! 2814: X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), ! 2815: X509_V_FLAG_TRUSTED_FIRST); ! 2816: #endif ! 2817: #ifdef X509_V_FLAG_PARTIAL_CHAIN ! 2818: if(!SSL_SET_OPTION(no_partialchain)) { ! 2819: /* Have intermediate certificates in the trust store be treated as ! 2820: trust-anchors, in the same way as self-signed root CA certificates ! 2821: are. This allows users to verify servers using the intermediate cert ! 2822: only, instead of needing the whole chain. */ ! 2823: X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), ! 2824: X509_V_FLAG_PARTIAL_CHAIN); ! 2825: } ! 2826: #endif ! 2827: } ! 2828: ! 2829: /* SSL always tries to verify the peer, this only says whether it should ! 2830: * fail to connect if the verification fails, or if it should continue ! 2831: * anyway. In the latter case the result of the verification is checked with ! 2832: * SSL_get_verify_result() below. */ ! 2833: SSL_CTX_set_verify(backend->ctx, ! 2834: verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); ! 2835: ! 2836: /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ ! 2837: #if defined(ENABLE_SSLKEYLOGFILE) && defined(HAVE_KEYLOG_CALLBACK) ! 2838: if(keylog_file_fp) { ! 2839: SSL_CTX_set_keylog_callback(backend->ctx, ossl_keylog_callback); ! 2840: } ! 2841: #endif ! 2842: ! 2843: /* Enable the session cache because it's a prerequisite for the "new session" ! 2844: * callback. Use the "external storage" mode to avoid that OpenSSL creates ! 2845: * an internal session cache. ! 2846: */ ! 2847: SSL_CTX_set_session_cache_mode(backend->ctx, ! 2848: SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); ! 2849: SSL_CTX_sess_set_new_cb(backend->ctx, ossl_new_session_cb); ! 2850: ! 2851: /* give application a chance to interfere with SSL set up. */ ! 2852: if(data->set.ssl.fsslctx) { ! 2853: Curl_set_in_callback(data, true); ! 2854: result = (*data->set.ssl.fsslctx)(data, backend->ctx, ! 2855: data->set.ssl.fsslctxp); ! 2856: Curl_set_in_callback(data, false); ! 2857: if(result) { ! 2858: failf(data, "error signaled by ssl ctx callback"); ! 2859: return result; ! 2860: } ! 2861: } ! 2862: ! 2863: /* Lets make an SSL structure */ ! 2864: if(backend->handle) ! 2865: SSL_free(backend->handle); ! 2866: backend->handle = SSL_new(backend->ctx); ! 2867: if(!backend->handle) { ! 2868: failf(data, "SSL: couldn't create a context (handle)!"); ! 2869: return CURLE_OUT_OF_MEMORY; ! 2870: } ! 2871: ! 2872: #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ ! 2873: !defined(OPENSSL_NO_OCSP) ! 2874: if(SSL_CONN_CONFIG(verifystatus)) ! 2875: SSL_set_tlsext_status_type(backend->handle, TLSEXT_STATUSTYPE_ocsp); ! 2876: #endif ! 2877: ! 2878: #if defined(OPENSSL_IS_BORINGSSL) && defined(ALLOW_RENEG) ! 2879: SSL_set_renegotiate_mode(backend->handle, ssl_renegotiate_freely); ! 2880: #endif ! 2881: ! 2882: SSL_set_connect_state(backend->handle); ! 2883: ! 2884: backend->server_cert = 0x0; ! 2885: #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME ! 2886: if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) && ! 2887: #ifdef ENABLE_IPV6 ! 2888: (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && ! 2889: #endif ! 2890: sni && ! 2891: !SSL_set_tlsext_host_name(backend->handle, hostname)) ! 2892: infof(data, "WARNING: failed to configure server name indication (SNI) " ! 2893: "TLS extension\n"); ! 2894: #endif ! 2895: ! 2896: /* Check if there's a cached ID we can/should use here! */ ! 2897: if(SSL_SET_OPTION(primary.sessionid)) { ! 2898: void *ssl_sessionid = NULL; ! 2899: int connectdata_idx = ossl_get_ssl_conn_index(); ! 2900: int sockindex_idx = ossl_get_ssl_sockindex_index(); ! 2901: ! 2902: if(connectdata_idx >= 0 && sockindex_idx >= 0) { ! 2903: /* Store the data needed for the "new session" callback. ! 2904: * The sockindex is stored as a pointer to an array element. */ ! 2905: SSL_set_ex_data(backend->handle, connectdata_idx, conn); ! 2906: SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); ! 2907: } ! 2908: ! 2909: Curl_ssl_sessionid_lock(conn); ! 2910: if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { ! 2911: /* we got a session id, use it! */ ! 2912: if(!SSL_set_session(backend->handle, ssl_sessionid)) { ! 2913: Curl_ssl_sessionid_unlock(conn); ! 2914: failf(data, "SSL: SSL_set_session failed: %s", ! 2915: ossl_strerror(ERR_get_error(), error_buffer, ! 2916: sizeof(error_buffer))); ! 2917: return CURLE_SSL_CONNECT_ERROR; ! 2918: } ! 2919: /* Informational message */ ! 2920: infof(data, "SSL re-using session ID\n"); ! 2921: } ! 2922: Curl_ssl_sessionid_unlock(conn); ! 2923: } ! 2924: ! 2925: if(conn->proxy_ssl[sockindex].use) { ! 2926: BIO *const bio = BIO_new(BIO_f_ssl()); ! 2927: SSL *handle = conn->proxy_ssl[sockindex].backend->handle; ! 2928: DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state); ! 2929: DEBUGASSERT(handle != NULL); ! 2930: DEBUGASSERT(bio != NULL); ! 2931: BIO_set_ssl(bio, handle, FALSE); ! 2932: SSL_set_bio(backend->handle, bio, bio); ! 2933: } ! 2934: else if(!SSL_set_fd(backend->handle, (int)sockfd)) { ! 2935: /* pass the raw socket into the SSL layers */ ! 2936: failf(data, "SSL: SSL_set_fd failed: %s", ! 2937: ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer))); ! 2938: return CURLE_SSL_CONNECT_ERROR; ! 2939: } ! 2940: ! 2941: connssl->connecting_state = ssl_connect_2; ! 2942: ! 2943: return CURLE_OK; ! 2944: } ! 2945: ! 2946: static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) ! 2947: { ! 2948: struct Curl_easy *data = conn->data; ! 2949: int err; ! 2950: struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ! 2951: long * const certverifyresult = SSL_IS_PROXY() ? ! 2952: &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; ! 2953: struct ssl_backend_data *backend = connssl->backend; ! 2954: DEBUGASSERT(ssl_connect_2 == connssl->connecting_state ! 2955: || ssl_connect_2_reading == connssl->connecting_state ! 2956: || ssl_connect_2_writing == connssl->connecting_state); ! 2957: ! 2958: ERR_clear_error(); ! 2959: ! 2960: err = SSL_connect(backend->handle); ! 2961: /* If keylogging is enabled but the keylog callback is not supported then log ! 2962: secrets here, immediately after SSL_connect by using tap_ssl_key. */ ! 2963: #if defined(ENABLE_SSLKEYLOGFILE) && !defined(HAVE_KEYLOG_CALLBACK) ! 2964: tap_ssl_key(backend->handle, &backend->tap_state); ! 2965: #endif ! 2966: ! 2967: /* 1 is fine ! 2968: 0 is "not successful but was shut down controlled" ! 2969: <0 is "handshake was not successful, because a fatal error occurred" */ ! 2970: if(1 != err) { ! 2971: int detail = SSL_get_error(backend->handle, err); ! 2972: ! 2973: if(SSL_ERROR_WANT_READ == detail) { ! 2974: connssl->connecting_state = ssl_connect_2_reading; ! 2975: return CURLE_OK; ! 2976: } ! 2977: if(SSL_ERROR_WANT_WRITE == detail) { ! 2978: connssl->connecting_state = ssl_connect_2_writing; ! 2979: return CURLE_OK; ! 2980: } ! 2981: #ifdef SSL_ERROR_WANT_ASYNC ! 2982: if(SSL_ERROR_WANT_ASYNC == detail) { ! 2983: connssl->connecting_state = ssl_connect_2; ! 2984: return CURLE_OK; ! 2985: } ! 2986: #endif ! 2987: else { ! 2988: /* untreated error */ ! 2989: unsigned long errdetail; ! 2990: char error_buffer[256]=""; ! 2991: CURLcode result; ! 2992: long lerr; ! 2993: int lib; ! 2994: int reason; ! 2995: ! 2996: /* the connection failed, we're not waiting for anything else. */ ! 2997: connssl->connecting_state = ssl_connect_2; ! 2998: ! 2999: /* Get the earliest error code from the thread's error queue and removes ! 3000: the entry. */ ! 3001: errdetail = ERR_get_error(); ! 3002: ! 3003: /* Extract which lib and reason */ ! 3004: lib = ERR_GET_LIB(errdetail); ! 3005: reason = ERR_GET_REASON(errdetail); ! 3006: ! 3007: if((lib == ERR_LIB_SSL) && ! 3008: (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) { ! 3009: result = CURLE_PEER_FAILED_VERIFICATION; ! 3010: ! 3011: lerr = SSL_get_verify_result(backend->handle); ! 3012: if(lerr != X509_V_OK) { ! 3013: *certverifyresult = lerr; ! 3014: msnprintf(error_buffer, sizeof(error_buffer), ! 3015: "SSL certificate problem: %s", ! 3016: X509_verify_cert_error_string(lerr)); ! 3017: } ! 3018: else ! 3019: /* strcpy() is fine here as long as the string fits within ! 3020: error_buffer */ ! 3021: strcpy(error_buffer, "SSL certificate verification failed"); ! 3022: } ! 3023: else { ! 3024: result = CURLE_SSL_CONNECT_ERROR; ! 3025: ossl_strerror(errdetail, error_buffer, sizeof(error_buffer)); ! 3026: } ! 3027: ! 3028: /* detail is already set to the SSL error above */ ! 3029: ! 3030: /* If we e.g. use SSLv2 request-method and the server doesn't like us ! 3031: * (RST connection etc.), OpenSSL gives no explanation whatsoever and ! 3032: * the SO_ERROR is also lost. ! 3033: */ ! 3034: if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) { ! 3035: const char * const hostname = SSL_IS_PROXY() ? ! 3036: conn->http_proxy.host.name : conn->host.name; ! 3037: const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; ! 3038: char extramsg[80]=""; ! 3039: int sockerr = SOCKERRNO; ! 3040: if(sockerr && detail == SSL_ERROR_SYSCALL) ! 3041: Curl_strerror(sockerr, extramsg, sizeof(extramsg)); ! 3042: failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ", ! 3043: extramsg[0] ? extramsg : SSL_ERROR_to_str(detail), ! 3044: hostname, port); ! 3045: return result; ! 3046: } ! 3047: ! 3048: /* Could be a CERT problem */ ! 3049: failf(data, "%s", error_buffer); ! 3050: ! 3051: return result; ! 3052: } ! 3053: } ! 3054: else { ! 3055: /* we have been connected fine, we're not waiting for anything else. */ ! 3056: connssl->connecting_state = ssl_connect_3; ! 3057: ! 3058: /* Informational message */ ! 3059: infof(data, "SSL connection using %s / %s\n", ! 3060: get_ssl_version_txt(backend->handle), ! 3061: SSL_get_cipher(backend->handle)); ! 3062: ! 3063: #ifdef HAS_ALPN ! 3064: /* Sets data and len to negotiated protocol, len is 0 if no protocol was ! 3065: * negotiated ! 3066: */ ! 3067: if(conn->bits.tls_enable_alpn) { ! 3068: const unsigned char *neg_protocol; ! 3069: unsigned int len; ! 3070: SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len); ! 3071: if(len != 0) { ! 3072: infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol); ! 3073: ! 3074: #ifdef USE_NGHTTP2 ! 3075: if(len == NGHTTP2_PROTO_VERSION_ID_LEN && ! 3076: !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) { ! 3077: conn->negnpn = CURL_HTTP_VERSION_2; ! 3078: } ! 3079: else ! 3080: #endif ! 3081: if(len == ALPN_HTTP_1_1_LENGTH && ! 3082: !memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) { ! 3083: conn->negnpn = CURL_HTTP_VERSION_1_1; ! 3084: } ! 3085: } ! 3086: else ! 3087: infof(data, "ALPN, server did not agree to a protocol\n"); ! 3088: ! 3089: Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? ! 3090: BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); ! 3091: } ! 3092: #endif ! 3093: ! 3094: return CURLE_OK; ! 3095: } ! 3096: } ! 3097: ! 3098: static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len) ! 3099: { ! 3100: int i, ilen; ! 3101: ! 3102: ilen = (int)len; ! 3103: if(ilen < 0) ! 3104: return 1; /* buffer too big */ ! 3105: ! 3106: i = i2t_ASN1_OBJECT(buf, ilen, a); ! 3107: ! 3108: if(i >= ilen) ! 3109: return 1; /* buffer too small */ ! 3110: ! 3111: return 0; ! 3112: } ! 3113: ! 3114: #define push_certinfo(_label, _num) \ ! 3115: do { \ ! 3116: long info_len = BIO_get_mem_data(mem, &ptr); \ ! 3117: Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \ ! 3118: if(1 != BIO_reset(mem)) \ ! 3119: break; \ ! 3120: } while(0) ! 3121: ! 3122: static void pubkey_show(struct Curl_easy *data, ! 3123: BIO *mem, ! 3124: int num, ! 3125: const char *type, ! 3126: const char *name, ! 3127: #ifdef HAVE_OPAQUE_RSA_DSA_DH ! 3128: const ! 3129: #endif ! 3130: BIGNUM *bn) ! 3131: { ! 3132: char *ptr; ! 3133: char namebuf[32]; ! 3134: ! 3135: msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name); ! 3136: ! 3137: if(bn) ! 3138: BN_print(mem, bn); ! 3139: push_certinfo(namebuf, num); ! 3140: } ! 3141: ! 3142: #ifdef HAVE_OPAQUE_RSA_DSA_DH ! 3143: #define print_pubkey_BN(_type, _name, _num) \ ! 3144: pubkey_show(data, mem, _num, #_type, #_name, _name) ! 3145: ! 3146: #else ! 3147: #define print_pubkey_BN(_type, _name, _num) \ ! 3148: do { \ ! 3149: if(_type->_name) { \ ! 3150: pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \ ! 3151: } \ ! 3152: } while(0) ! 3153: #endif ! 3154: ! 3155: static void X509V3_ext(struct Curl_easy *data, ! 3156: int certnum, ! 3157: CONST_EXTS STACK_OF(X509_EXTENSION) *exts) ! 3158: { ! 3159: int i; ! 3160: ! 3161: if((int)sk_X509_EXTENSION_num(exts) <= 0) ! 3162: /* no extensions, bail out */ ! 3163: return; ! 3164: ! 3165: for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) { ! 3166: ASN1_OBJECT *obj; ! 3167: X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); ! 3168: BUF_MEM *biomem; ! 3169: char namebuf[128]; ! 3170: BIO *bio_out = BIO_new(BIO_s_mem()); ! 3171: ! 3172: if(!bio_out) ! 3173: return; ! 3174: ! 3175: obj = X509_EXTENSION_get_object(ext); ! 3176: ! 3177: asn1_object_dump(obj, namebuf, sizeof(namebuf)); ! 3178: ! 3179: if(!X509V3_EXT_print(bio_out, ext, 0, 0)) ! 3180: ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); ! 3181: ! 3182: BIO_get_mem_ptr(bio_out, &biomem); ! 3183: Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data, ! 3184: biomem->length); ! 3185: BIO_free(bio_out); ! 3186: } ! 3187: } ! 3188: ! 3189: #ifdef OPENSSL_IS_BORINGSSL ! 3190: typedef size_t numcert_t; ! 3191: #else ! 3192: typedef int numcert_t; ! 3193: #endif ! 3194: ! 3195: static CURLcode get_cert_chain(struct connectdata *conn, ! 3196: struct ssl_connect_data *connssl) ! 3197: ! 3198: { ! 3199: CURLcode result; ! 3200: STACK_OF(X509) *sk; ! 3201: int i; ! 3202: struct Curl_easy *data = conn->data; ! 3203: numcert_t numcerts; ! 3204: BIO *mem; ! 3205: struct ssl_backend_data *backend = connssl->backend; ! 3206: ! 3207: sk = SSL_get_peer_cert_chain(backend->handle); ! 3208: if(!sk) { ! 3209: return CURLE_OUT_OF_MEMORY; ! 3210: } ! 3211: ! 3212: numcerts = sk_X509_num(sk); ! 3213: ! 3214: result = Curl_ssl_init_certinfo(data, (int)numcerts); ! 3215: if(result) { ! 3216: return result; ! 3217: } ! 3218: ! 3219: mem = BIO_new(BIO_s_mem()); ! 3220: ! 3221: for(i = 0; i < (int)numcerts; i++) { ! 3222: ASN1_INTEGER *num; ! 3223: X509 *x = sk_X509_value(sk, i); ! 3224: EVP_PKEY *pubkey = NULL; ! 3225: int j; ! 3226: char *ptr; ! 3227: const ASN1_BIT_STRING *psig = NULL; ! 3228: ! 3229: X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); ! 3230: push_certinfo("Subject", i); ! 3231: ! 3232: X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); ! 3233: push_certinfo("Issuer", i); ! 3234: ! 3235: BIO_printf(mem, "%lx", X509_get_version(x)); ! 3236: push_certinfo("Version", i); ! 3237: ! 3238: num = X509_get_serialNumber(x); ! 3239: if(num->type == V_ASN1_NEG_INTEGER) ! 3240: BIO_puts(mem, "-"); ! 3241: for(j = 0; j < num->length; j++) ! 3242: BIO_printf(mem, "%02x", num->data[j]); ! 3243: push_certinfo("Serial Number", i); ! 3244: ! 3245: #if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS) ! 3246: { ! 3247: const X509_ALGOR *sigalg = NULL; ! 3248: X509_PUBKEY *xpubkey = NULL; ! 3249: ASN1_OBJECT *pubkeyoid = NULL; ! 3250: ! 3251: X509_get0_signature(&psig, &sigalg, x); ! 3252: if(sigalg) { ! 3253: i2a_ASN1_OBJECT(mem, sigalg->algorithm); ! 3254: push_certinfo("Signature Algorithm", i); ! 3255: } ! 3256: ! 3257: xpubkey = X509_get_X509_PUBKEY(x); ! 3258: if(xpubkey) { ! 3259: X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey); ! 3260: if(pubkeyoid) { ! 3261: i2a_ASN1_OBJECT(mem, pubkeyoid); ! 3262: push_certinfo("Public Key Algorithm", i); ! 3263: } ! 3264: } ! 3265: ! 3266: X509V3_ext(data, i, X509_get0_extensions(x)); ! 3267: } ! 3268: #else ! 3269: { ! 3270: /* before OpenSSL 1.0.2 */ ! 3271: X509_CINF *cinf = x->cert_info; ! 3272: ! 3273: i2a_ASN1_OBJECT(mem, cinf->signature->algorithm); ! 3274: push_certinfo("Signature Algorithm", i); ! 3275: ! 3276: i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm); ! 3277: push_certinfo("Public Key Algorithm", i); ! 3278: ! 3279: X509V3_ext(data, i, cinf->extensions); ! 3280: ! 3281: psig = x->signature; ! 3282: } ! 3283: #endif ! 3284: ! 3285: ASN1_TIME_print(mem, X509_get0_notBefore(x)); ! 3286: push_certinfo("Start date", i); ! 3287: ! 3288: ASN1_TIME_print(mem, X509_get0_notAfter(x)); ! 3289: push_certinfo("Expire date", i); ! 3290: ! 3291: pubkey = X509_get_pubkey(x); ! 3292: if(!pubkey) ! 3293: infof(data, " Unable to load public key\n"); ! 3294: else { ! 3295: int pktype; ! 3296: #ifdef HAVE_OPAQUE_EVP_PKEY ! 3297: pktype = EVP_PKEY_id(pubkey); ! 3298: #else ! 3299: pktype = pubkey->type; ! 3300: #endif ! 3301: switch(pktype) { ! 3302: case EVP_PKEY_RSA: ! 3303: { ! 3304: RSA *rsa; ! 3305: #ifdef HAVE_OPAQUE_EVP_PKEY ! 3306: rsa = EVP_PKEY_get0_RSA(pubkey); ! 3307: #else ! 3308: rsa = pubkey->pkey.rsa; ! 3309: #endif ! 3310: ! 3311: #ifdef HAVE_OPAQUE_RSA_DSA_DH ! 3312: { ! 3313: const BIGNUM *n; ! 3314: const BIGNUM *e; ! 3315: ! 3316: RSA_get0_key(rsa, &n, &e, NULL); ! 3317: BIO_printf(mem, "%d", BN_num_bits(n)); ! 3318: push_certinfo("RSA Public Key", i); ! 3319: print_pubkey_BN(rsa, n, i); ! 3320: print_pubkey_BN(rsa, e, i); ! 3321: } ! 3322: #else ! 3323: BIO_printf(mem, "%d", BN_num_bits(rsa->n)); ! 3324: push_certinfo("RSA Public Key", i); ! 3325: print_pubkey_BN(rsa, n, i); ! 3326: print_pubkey_BN(rsa, e, i); ! 3327: #endif ! 3328: ! 3329: break; ! 3330: } ! 3331: case EVP_PKEY_DSA: ! 3332: { ! 3333: #ifndef OPENSSL_NO_DSA ! 3334: DSA *dsa; ! 3335: #ifdef HAVE_OPAQUE_EVP_PKEY ! 3336: dsa = EVP_PKEY_get0_DSA(pubkey); ! 3337: #else ! 3338: dsa = pubkey->pkey.dsa; ! 3339: #endif ! 3340: #ifdef HAVE_OPAQUE_RSA_DSA_DH ! 3341: { ! 3342: const BIGNUM *p; ! 3343: const BIGNUM *q; ! 3344: const BIGNUM *g; ! 3345: const BIGNUM *pub_key; ! 3346: ! 3347: DSA_get0_pqg(dsa, &p, &q, &g); ! 3348: DSA_get0_key(dsa, &pub_key, NULL); ! 3349: ! 3350: print_pubkey_BN(dsa, p, i); ! 3351: print_pubkey_BN(dsa, q, i); ! 3352: print_pubkey_BN(dsa, g, i); ! 3353: print_pubkey_BN(dsa, pub_key, i); ! 3354: } ! 3355: #else ! 3356: print_pubkey_BN(dsa, p, i); ! 3357: print_pubkey_BN(dsa, q, i); ! 3358: print_pubkey_BN(dsa, g, i); ! 3359: print_pubkey_BN(dsa, pub_key, i); ! 3360: #endif ! 3361: #endif /* !OPENSSL_NO_DSA */ ! 3362: break; ! 3363: } ! 3364: case EVP_PKEY_DH: ! 3365: { ! 3366: DH *dh; ! 3367: #ifdef HAVE_OPAQUE_EVP_PKEY ! 3368: dh = EVP_PKEY_get0_DH(pubkey); ! 3369: #else ! 3370: dh = pubkey->pkey.dh; ! 3371: #endif ! 3372: #ifdef HAVE_OPAQUE_RSA_DSA_DH ! 3373: { ! 3374: const BIGNUM *p; ! 3375: const BIGNUM *q; ! 3376: const BIGNUM *g; ! 3377: const BIGNUM *pub_key; ! 3378: DH_get0_pqg(dh, &p, &q, &g); ! 3379: DH_get0_key(dh, &pub_key, NULL); ! 3380: print_pubkey_BN(dh, p, i); ! 3381: print_pubkey_BN(dh, q, i); ! 3382: print_pubkey_BN(dh, g, i); ! 3383: print_pubkey_BN(dh, pub_key, i); ! 3384: } ! 3385: #else ! 3386: print_pubkey_BN(dh, p, i); ! 3387: print_pubkey_BN(dh, g, i); ! 3388: print_pubkey_BN(dh, pub_key, i); ! 3389: #endif ! 3390: break; ! 3391: } ! 3392: } ! 3393: EVP_PKEY_free(pubkey); ! 3394: } ! 3395: ! 3396: if(psig) { ! 3397: for(j = 0; j < psig->length; j++) ! 3398: BIO_printf(mem, "%02x:", psig->data[j]); ! 3399: push_certinfo("Signature", i); ! 3400: } ! 3401: ! 3402: PEM_write_bio_X509(mem, x); ! 3403: push_certinfo("Cert", i); ! 3404: } ! 3405: ! 3406: BIO_free(mem); ! 3407: ! 3408: return CURLE_OK; ! 3409: } ! 3410: ! 3411: /* ! 3412: * Heavily modified from: ! 3413: * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL ! 3414: */ ! 3415: static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert, ! 3416: const char *pinnedpubkey) ! 3417: { ! 3418: /* Scratch */ ! 3419: int len1 = 0, len2 = 0; ! 3420: unsigned char *buff1 = NULL, *temp = NULL; ! 3421: ! 3422: /* Result is returned to caller */ ! 3423: CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; ! 3424: ! 3425: /* if a path wasn't specified, don't pin */ ! 3426: if(!pinnedpubkey) ! 3427: return CURLE_OK; ! 3428: ! 3429: if(!cert) ! 3430: return result; ! 3431: ! 3432: do { ! 3433: /* Begin Gyrations to get the subjectPublicKeyInfo */ ! 3434: /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */ ! 3435: ! 3436: /* https://groups.google.com/group/mailing.openssl.users/browse_thread ! 3437: /thread/d61858dae102c6c7 */ ! 3438: len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL); ! 3439: if(len1 < 1) ! 3440: break; /* failed */ ! 3441: ! 3442: buff1 = temp = malloc(len1); ! 3443: if(!buff1) ! 3444: break; /* failed */ ! 3445: ! 3446: /* https://www.openssl.org/docs/crypto/d2i_X509.html */ ! 3447: len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp); ! 3448: ! 3449: /* ! 3450: * These checks are verifying we got back the same values as when we ! 3451: * sized the buffer. It's pretty weak since they should always be the ! 3452: * same. But it gives us something to test. ! 3453: */ ! 3454: if((len1 != len2) || !temp || ((temp - buff1) != len1)) ! 3455: break; /* failed */ ! 3456: ! 3457: /* End Gyrations */ ! 3458: ! 3459: /* The one good exit point */ ! 3460: result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); ! 3461: } while(0); ! 3462: ! 3463: if(buff1) ! 3464: free(buff1); ! 3465: ! 3466: return result; ! 3467: } ! 3468: ! 3469: /* ! 3470: * Get the server cert, verify it and show it etc, only call failf() if the ! 3471: * 'strict' argument is TRUE as otherwise all this is for informational ! 3472: * purposes only! ! 3473: * ! 3474: * We check certificates to authenticate the server; otherwise we risk ! 3475: * man-in-the-middle attack. ! 3476: */ ! 3477: static CURLcode servercert(struct connectdata *conn, ! 3478: struct ssl_connect_data *connssl, ! 3479: bool strict) ! 3480: { ! 3481: CURLcode result = CURLE_OK; ! 3482: int rc; ! 3483: long lerr; ! 3484: struct Curl_easy *data = conn->data; ! 3485: X509 *issuer; ! 3486: BIO *fp = NULL; ! 3487: char error_buffer[256]=""; ! 3488: char buffer[2048]; ! 3489: const char *ptr; ! 3490: long * const certverifyresult = SSL_IS_PROXY() ? ! 3491: &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; ! 3492: BIO *mem = BIO_new(BIO_s_mem()); ! 3493: struct ssl_backend_data *backend = connssl->backend; ! 3494: ! 3495: if(data->set.ssl.certinfo) ! 3496: /* we've been asked to gather certificate info! */ ! 3497: (void)get_cert_chain(conn, connssl); ! 3498: ! 3499: backend->server_cert = SSL_get_peer_certificate(backend->handle); ! 3500: if(!backend->server_cert) { ! 3501: BIO_free(mem); ! 3502: if(!strict) ! 3503: return CURLE_OK; ! 3504: ! 3505: failf(data, "SSL: couldn't get peer certificate!"); ! 3506: return CURLE_PEER_FAILED_VERIFICATION; ! 3507: } ! 3508: ! 3509: infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server"); ! 3510: ! 3511: rc = x509_name_oneline(X509_get_subject_name(backend->server_cert), ! 3512: buffer, sizeof(buffer)); ! 3513: infof(data, " subject: %s\n", rc?"[NONE]":buffer); ! 3514: ! 3515: #ifndef CURL_DISABLE_VERBOSE_STRINGS ! 3516: { ! 3517: long len; ! 3518: ASN1_TIME_print(mem, X509_get0_notBefore(backend->server_cert)); ! 3519: len = BIO_get_mem_data(mem, (char **) &ptr); ! 3520: infof(data, " start date: %.*s\n", len, ptr); ! 3521: (void)BIO_reset(mem); ! 3522: ! 3523: ASN1_TIME_print(mem, X509_get0_notAfter(backend->server_cert)); ! 3524: len = BIO_get_mem_data(mem, (char **) &ptr); ! 3525: infof(data, " expire date: %.*s\n", len, ptr); ! 3526: (void)BIO_reset(mem); ! 3527: } ! 3528: #endif ! 3529: ! 3530: BIO_free(mem); ! 3531: ! 3532: if(SSL_CONN_CONFIG(verifyhost)) { ! 3533: result = verifyhost(conn, backend->server_cert); ! 3534: if(result) { ! 3535: X509_free(backend->server_cert); ! 3536: backend->server_cert = NULL; ! 3537: return result; ! 3538: } ! 3539: } ! 3540: ! 3541: rc = x509_name_oneline(X509_get_issuer_name(backend->server_cert), ! 3542: buffer, sizeof(buffer)); ! 3543: if(rc) { ! 3544: if(strict) ! 3545: failf(data, "SSL: couldn't get X509-issuer name!"); ! 3546: result = CURLE_PEER_FAILED_VERIFICATION; ! 3547: } ! 3548: else { ! 3549: infof(data, " issuer: %s\n", buffer); ! 3550: ! 3551: /* We could do all sorts of certificate verification stuff here before ! 3552: deallocating the certificate. */ ! 3553: ! 3554: /* e.g. match issuer name with provided issuer certificate */ ! 3555: if(SSL_SET_OPTION(issuercert)) { ! 3556: fp = BIO_new(BIO_s_file()); ! 3557: if(fp == NULL) { ! 3558: failf(data, ! 3559: "BIO_new return NULL, " OSSL_PACKAGE ! 3560: " error %s", ! 3561: ossl_strerror(ERR_get_error(), error_buffer, ! 3562: sizeof(error_buffer)) ); ! 3563: X509_free(backend->server_cert); ! 3564: backend->server_cert = NULL; ! 3565: return CURLE_OUT_OF_MEMORY; ! 3566: } ! 3567: ! 3568: if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { ! 3569: if(strict) ! 3570: failf(data, "SSL: Unable to open issuer cert (%s)", ! 3571: SSL_SET_OPTION(issuercert)); ! 3572: BIO_free(fp); ! 3573: X509_free(backend->server_cert); ! 3574: backend->server_cert = NULL; ! 3575: return CURLE_SSL_ISSUER_ERROR; ! 3576: } ! 3577: ! 3578: issuer = PEM_read_bio_X509(fp, NULL, ZERO_NULL, NULL); ! 3579: if(!issuer) { ! 3580: if(strict) ! 3581: failf(data, "SSL: Unable to read issuer cert (%s)", ! 3582: SSL_SET_OPTION(issuercert)); ! 3583: BIO_free(fp); ! 3584: X509_free(issuer); ! 3585: X509_free(backend->server_cert); ! 3586: backend->server_cert = NULL; ! 3587: return CURLE_SSL_ISSUER_ERROR; ! 3588: } ! 3589: ! 3590: if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) { ! 3591: if(strict) ! 3592: failf(data, "SSL: Certificate issuer check failed (%s)", ! 3593: SSL_SET_OPTION(issuercert)); ! 3594: BIO_free(fp); ! 3595: X509_free(issuer); ! 3596: X509_free(backend->server_cert); ! 3597: backend->server_cert = NULL; ! 3598: return CURLE_SSL_ISSUER_ERROR; ! 3599: } ! 3600: ! 3601: infof(data, " SSL certificate issuer check ok (%s)\n", ! 3602: SSL_SET_OPTION(issuercert)); ! 3603: BIO_free(fp); ! 3604: X509_free(issuer); ! 3605: } ! 3606: ! 3607: lerr = *certverifyresult = SSL_get_verify_result(backend->handle); ! 3608: ! 3609: if(*certverifyresult != X509_V_OK) { ! 3610: if(SSL_CONN_CONFIG(verifypeer)) { ! 3611: /* We probably never reach this, because SSL_connect() will fail ! 3612: and we return earlier if verifypeer is set? */ ! 3613: if(strict) ! 3614: failf(data, "SSL certificate verify result: %s (%ld)", ! 3615: X509_verify_cert_error_string(lerr), lerr); ! 3616: result = CURLE_PEER_FAILED_VERIFICATION; ! 3617: } ! 3618: else ! 3619: infof(data, " SSL certificate verify result: %s (%ld)," ! 3620: " continuing anyway.\n", ! 3621: X509_verify_cert_error_string(lerr), lerr); ! 3622: } ! 3623: else ! 3624: infof(data, " SSL certificate verify ok.\n"); ! 3625: } ! 3626: ! 3627: #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ ! 3628: !defined(OPENSSL_NO_OCSP) ! 3629: if(SSL_CONN_CONFIG(verifystatus)) { ! 3630: result = verifystatus(conn, connssl); ! 3631: if(result) { ! 3632: X509_free(backend->server_cert); ! 3633: backend->server_cert = NULL; ! 3634: return result; ! 3635: } ! 3636: } ! 3637: #endif ! 3638: ! 3639: if(!strict) ! 3640: /* when not strict, we don't bother about the verify cert problems */ ! 3641: result = CURLE_OK; ! 3642: ! 3643: ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : ! 3644: data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ! 3645: if(!result && ptr) { ! 3646: result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr); ! 3647: if(result) ! 3648: failf(data, "SSL: public key does not match pinned public key!"); ! 3649: } ! 3650: ! 3651: X509_free(backend->server_cert); ! 3652: backend->server_cert = NULL; ! 3653: connssl->connecting_state = ssl_connect_done; ! 3654: ! 3655: return result; ! 3656: } ! 3657: ! 3658: static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex) ! 3659: { ! 3660: CURLcode result = CURLE_OK; ! 3661: struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ! 3662: ! 3663: DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); ! 3664: ! 3665: /* ! 3666: * We check certificates to authenticate the server; otherwise we risk ! 3667: * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to ! 3668: * verify the peer ignore faults and failures from the server cert ! 3669: * operations. ! 3670: */ ! 3671: ! 3672: result = servercert(conn, connssl, (SSL_CONN_CONFIG(verifypeer) || ! 3673: SSL_CONN_CONFIG(verifyhost))); ! 3674: ! 3675: if(!result) ! 3676: connssl->connecting_state = ssl_connect_done; ! 3677: ! 3678: return result; ! 3679: } ! 3680: ! 3681: static Curl_recv ossl_recv; ! 3682: static Curl_send ossl_send; ! 3683: ! 3684: static CURLcode ossl_connect_common(struct connectdata *conn, ! 3685: int sockindex, ! 3686: bool nonblocking, ! 3687: bool *done) ! 3688: { ! 3689: CURLcode result; ! 3690: struct Curl_easy *data = conn->data; ! 3691: struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ! 3692: curl_socket_t sockfd = conn->sock[sockindex]; ! 3693: timediff_t timeout_ms; ! 3694: int what; ! 3695: ! 3696: /* check if the connection has already been established */ ! 3697: if(ssl_connection_complete == connssl->state) { ! 3698: *done = TRUE; ! 3699: return CURLE_OK; ! 3700: } ! 3701: ! 3702: if(ssl_connect_1 == connssl->connecting_state) { ! 3703: /* Find out how much more time we're allowed */ ! 3704: timeout_ms = Curl_timeleft(data, NULL, TRUE); ! 3705: ! 3706: if(timeout_ms < 0) { ! 3707: /* no need to continue if time already is up */ ! 3708: failf(data, "SSL connection timeout"); ! 3709: return CURLE_OPERATION_TIMEDOUT; ! 3710: } ! 3711: ! 3712: result = ossl_connect_step1(conn, sockindex); ! 3713: if(result) ! 3714: return result; ! 3715: } ! 3716: ! 3717: while(ssl_connect_2 == connssl->connecting_state || ! 3718: ssl_connect_2_reading == connssl->connecting_state || ! 3719: ssl_connect_2_writing == connssl->connecting_state) { ! 3720: ! 3721: /* check allowed time left */ ! 3722: timeout_ms = Curl_timeleft(data, NULL, TRUE); ! 3723: ! 3724: if(timeout_ms < 0) { ! 3725: /* no need to continue if time already is up */ ! 3726: failf(data, "SSL connection timeout"); ! 3727: return CURLE_OPERATION_TIMEDOUT; ! 3728: } ! 3729: ! 3730: /* if ssl is expecting something, check if it's available. */ ! 3731: if(connssl->connecting_state == ssl_connect_2_reading || ! 3732: connssl->connecting_state == ssl_connect_2_writing) { ! 3733: ! 3734: curl_socket_t writefd = ssl_connect_2_writing == ! 3735: connssl->connecting_state?sockfd:CURL_SOCKET_BAD; ! 3736: curl_socket_t readfd = ssl_connect_2_reading == ! 3737: connssl->connecting_state?sockfd:CURL_SOCKET_BAD; ! 3738: ! 3739: what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, ! 3740: nonblocking?0:(time_t)timeout_ms); ! 3741: if(what < 0) { ! 3742: /* fatal error */ ! 3743: failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); ! 3744: return CURLE_SSL_CONNECT_ERROR; ! 3745: } ! 3746: if(0 == what) { ! 3747: if(nonblocking) { ! 3748: *done = FALSE; ! 3749: return CURLE_OK; ! 3750: } ! 3751: /* timeout */ ! 3752: failf(data, "SSL connection timeout"); ! 3753: return CURLE_OPERATION_TIMEDOUT; ! 3754: } ! 3755: /* socket is readable or writable */ ! 3756: } ! 3757: ! 3758: /* Run transaction, and return to the caller if it failed or if this ! 3759: * connection is done nonblocking and this loop would execute again. This ! 3760: * permits the owner of a multi handle to abort a connection attempt ! 3761: * before step2 has completed while ensuring that a client using select() ! 3762: * or epoll() will always have a valid fdset to wait on. ! 3763: */ ! 3764: result = ossl_connect_step2(conn, sockindex); ! 3765: if(result || (nonblocking && ! 3766: (ssl_connect_2 == connssl->connecting_state || ! 3767: ssl_connect_2_reading == connssl->connecting_state || ! 3768: ssl_connect_2_writing == connssl->connecting_state))) ! 3769: return result; ! 3770: ! 3771: } /* repeat step2 until all transactions are done. */ ! 3772: ! 3773: if(ssl_connect_3 == connssl->connecting_state) { ! 3774: result = ossl_connect_step3(conn, sockindex); ! 3775: if(result) ! 3776: return result; ! 3777: } ! 3778: ! 3779: if(ssl_connect_done == connssl->connecting_state) { ! 3780: connssl->state = ssl_connection_complete; ! 3781: conn->recv[sockindex] = ossl_recv; ! 3782: conn->send[sockindex] = ossl_send; ! 3783: *done = TRUE; ! 3784: } ! 3785: else ! 3786: *done = FALSE; ! 3787: ! 3788: /* Reset our connect state machine */ ! 3789: connssl->connecting_state = ssl_connect_1; ! 3790: ! 3791: return CURLE_OK; ! 3792: } ! 3793: ! 3794: static CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn, ! 3795: int sockindex, ! 3796: bool *done) ! 3797: { ! 3798: return ossl_connect_common(conn, sockindex, TRUE, done); ! 3799: } ! 3800: ! 3801: static CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex) ! 3802: { ! 3803: CURLcode result; ! 3804: bool done = FALSE; ! 3805: ! 3806: result = ossl_connect_common(conn, sockindex, FALSE, &done); ! 3807: if(result) ! 3808: return result; ! 3809: ! 3810: DEBUGASSERT(done); ! 3811: ! 3812: return CURLE_OK; ! 3813: } ! 3814: ! 3815: static bool Curl_ossl_data_pending(const struct connectdata *conn, ! 3816: int connindex) ! 3817: { ! 3818: const struct ssl_connect_data *connssl = &conn->ssl[connindex]; ! 3819: const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex]; ! 3820: ! 3821: if(connssl->backend->handle && SSL_pending(connssl->backend->handle)) ! 3822: return TRUE; ! 3823: ! 3824: if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle)) ! 3825: return TRUE; ! 3826: ! 3827: return FALSE; ! 3828: } ! 3829: ! 3830: static size_t Curl_ossl_version(char *buffer, size_t size); ! 3831: ! 3832: static ssize_t ossl_send(struct connectdata *conn, ! 3833: int sockindex, ! 3834: const void *mem, ! 3835: size_t len, ! 3836: CURLcode *curlcode) ! 3837: { ! 3838: /* SSL_write() is said to return 'int' while write() and send() returns ! 3839: 'size_t' */ ! 3840: int err; ! 3841: char error_buffer[256]; ! 3842: unsigned long sslerror; ! 3843: int memlen; ! 3844: int rc; ! 3845: struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ! 3846: struct ssl_backend_data *backend = connssl->backend; ! 3847: ! 3848: ERR_clear_error(); ! 3849: ! 3850: memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; ! 3851: rc = SSL_write(backend->handle, mem, memlen); ! 3852: ! 3853: if(rc <= 0) { ! 3854: err = SSL_get_error(backend->handle, rc); ! 3855: ! 3856: switch(err) { ! 3857: case SSL_ERROR_WANT_READ: ! 3858: case SSL_ERROR_WANT_WRITE: ! 3859: /* The operation did not complete; the same TLS/SSL I/O function ! 3860: should be called again later. This is basically an EWOULDBLOCK ! 3861: equivalent. */ ! 3862: *curlcode = CURLE_AGAIN; ! 3863: return -1; ! 3864: case SSL_ERROR_SYSCALL: ! 3865: { ! 3866: int sockerr = SOCKERRNO; ! 3867: sslerror = ERR_get_error(); ! 3868: if(sslerror) ! 3869: ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); ! 3870: else if(sockerr) ! 3871: Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); ! 3872: else { ! 3873: strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); ! 3874: error_buffer[sizeof(error_buffer) - 1] = '\0'; ! 3875: } ! 3876: failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d", ! 3877: error_buffer, sockerr); ! 3878: *curlcode = CURLE_SEND_ERROR; ! 3879: return -1; ! 3880: } ! 3881: case SSL_ERROR_SSL: ! 3882: /* A failure in the SSL library occurred, usually a protocol error. ! 3883: The OpenSSL error queue contains more information on the error. */ ! 3884: sslerror = ERR_get_error(); ! 3885: if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL && ! 3886: ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET && ! 3887: conn->ssl[sockindex].state == ssl_connection_complete && ! 3888: conn->proxy_ssl[sockindex].state == ssl_connection_complete) { ! 3889: char ver[120]; ! 3890: Curl_ossl_version(ver, 120); ! 3891: failf(conn->data, "Error: %s does not support double SSL tunneling.", ! 3892: ver); ! 3893: } ! 3894: else ! 3895: failf(conn->data, "SSL_write() error: %s", ! 3896: ossl_strerror(sslerror, error_buffer, sizeof(error_buffer))); ! 3897: *curlcode = CURLE_SEND_ERROR; ! 3898: return -1; ! 3899: } ! 3900: /* a true error */ ! 3901: failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d", ! 3902: SSL_ERROR_to_str(err), SOCKERRNO); ! 3903: *curlcode = CURLE_SEND_ERROR; ! 3904: return -1; ! 3905: } ! 3906: *curlcode = CURLE_OK; ! 3907: return (ssize_t)rc; /* number of bytes */ ! 3908: } ! 3909: ! 3910: static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ ! 3911: int num, /* socketindex */ ! 3912: char *buf, /* store read data here */ ! 3913: size_t buffersize, /* max amount to read */ ! 3914: CURLcode *curlcode) ! 3915: { ! 3916: char error_buffer[256]; ! 3917: unsigned long sslerror; ! 3918: ssize_t nread; ! 3919: int buffsize; ! 3920: struct ssl_connect_data *connssl = &conn->ssl[num]; ! 3921: struct ssl_backend_data *backend = connssl->backend; ! 3922: ! 3923: ERR_clear_error(); ! 3924: ! 3925: buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; ! 3926: nread = (ssize_t)SSL_read(backend->handle, buf, buffsize); ! 3927: if(nread <= 0) { ! 3928: /* failed SSL_read */ ! 3929: int err = SSL_get_error(backend->handle, (int)nread); ! 3930: ! 3931: switch(err) { ! 3932: case SSL_ERROR_NONE: /* this is not an error */ ! 3933: break; ! 3934: case SSL_ERROR_ZERO_RETURN: /* no more data */ ! 3935: /* close_notify alert */ ! 3936: if(num == FIRSTSOCKET) ! 3937: /* mark the connection for close if it is indeed the control ! 3938: connection */ ! 3939: connclose(conn, "TLS close_notify"); ! 3940: break; ! 3941: case SSL_ERROR_WANT_READ: ! 3942: case SSL_ERROR_WANT_WRITE: ! 3943: /* there's data pending, re-invoke SSL_read() */ ! 3944: *curlcode = CURLE_AGAIN; ! 3945: return -1; ! 3946: default: ! 3947: /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return ! 3948: value/errno" */ ! 3949: /* https://www.openssl.org/docs/crypto/ERR_get_error.html */ ! 3950: sslerror = ERR_get_error(); ! 3951: if((nread < 0) || sslerror) { ! 3952: /* If the return code was negative or there actually is an error in the ! 3953: queue */ ! 3954: int sockerr = SOCKERRNO; ! 3955: if(sslerror) ! 3956: ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); ! 3957: else if(sockerr && err == SSL_ERROR_SYSCALL) ! 3958: Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); ! 3959: else { ! 3960: strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); ! 3961: error_buffer[sizeof(error_buffer) - 1] = '\0'; ! 3962: } ! 3963: failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d", ! 3964: error_buffer, sockerr); ! 3965: *curlcode = CURLE_RECV_ERROR; ! 3966: return -1; ! 3967: } ! 3968: /* For debug builds be a little stricter and error on any ! 3969: SSL_ERROR_SYSCALL. For example a server may have closed the connection ! 3970: abruptly without a close_notify alert. For compatibility with older ! 3971: peers we don't do this by default. #4624 ! 3972: ! 3973: We can use this to gauge how many users may be affected, and ! 3974: if it goes ok eventually transition to allow in dev and release with ! 3975: the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ ! 3976: #ifdef DEBUGBUILD ! 3977: if(err == SSL_ERROR_SYSCALL) { ! 3978: int sockerr = SOCKERRNO; ! 3979: if(sockerr) ! 3980: Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); ! 3981: else { ! 3982: msnprintf(error_buffer, sizeof(error_buffer), ! 3983: "Connection closed abruptly"); ! 3984: } ! 3985: failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d" ! 3986: " (Fatal because this is a curl debug build)", ! 3987: error_buffer, sockerr); ! 3988: *curlcode = CURLE_RECV_ERROR; ! 3989: return -1; ! 3990: } ! 3991: #endif ! 3992: } ! 3993: } ! 3994: return nread; ! 3995: } ! 3996: ! 3997: static size_t Curl_ossl_version(char *buffer, size_t size) ! 3998: { ! 3999: #ifdef LIBRESSL_VERSION_NUMBER ! 4000: #if LIBRESSL_VERSION_NUMBER < 0x2070100fL ! 4001: return msnprintf(buffer, size, "%s/%lx.%lx.%lx", ! 4002: OSSL_PACKAGE, ! 4003: (LIBRESSL_VERSION_NUMBER>>28)&0xf, ! 4004: (LIBRESSL_VERSION_NUMBER>>20)&0xff, ! 4005: (LIBRESSL_VERSION_NUMBER>>12)&0xff); ! 4006: #else /* OpenSSL_version() first appeared in LibreSSL 2.7.1 */ ! 4007: char *p; ! 4008: int count; ! 4009: const char *ver = OpenSSL_version(OPENSSL_VERSION); ! 4010: const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ ! 4011: if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) { ! 4012: ver += sizeof(expected) - 1; ! 4013: } ! 4014: count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); ! 4015: for(p = buffer; *p; ++p) { ! 4016: if(ISSPACE(*p)) ! 4017: *p = '_'; ! 4018: } ! 4019: return count; ! 4020: #endif ! 4021: #elif defined(OPENSSL_IS_BORINGSSL) ! 4022: return msnprintf(buffer, size, OSSL_PACKAGE); ! 4023: #elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING) ! 4024: return msnprintf(buffer, size, "%s/%s", ! 4025: OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); ! 4026: #else ! 4027: /* not LibreSSL, BoringSSL and not using OpenSSL_version */ ! 4028: ! 4029: char sub[3]; ! 4030: unsigned long ssleay_value; ! 4031: sub[2]='\0'; ! 4032: sub[1]='\0'; ! 4033: ssleay_value = OpenSSL_version_num(); ! 4034: if(ssleay_value < 0x906000) { ! 4035: ssleay_value = SSLEAY_VERSION_NUMBER; ! 4036: sub[0]='\0'; ! 4037: } ! 4038: else { ! 4039: if(ssleay_value&0xff0) { ! 4040: int minor_ver = (ssleay_value >> 4) & 0xff; ! 4041: if(minor_ver > 26) { ! 4042: /* handle extended version introduced for 0.9.8za */ ! 4043: sub[1] = (char) ((minor_ver - 1) % 26 + 'a' + 1); ! 4044: sub[0] = 'z'; ! 4045: } ! 4046: else { ! 4047: sub[0] = (char) (minor_ver + 'a' - 1); ! 4048: } ! 4049: } ! 4050: else ! 4051: sub[0]='\0'; ! 4052: } ! 4053: ! 4054: return msnprintf(buffer, size, "%s/%lx.%lx.%lx%s" ! 4055: #ifdef OPENSSL_FIPS ! 4056: "-fips" ! 4057: #endif ! 4058: , ! 4059: OSSL_PACKAGE, ! 4060: (ssleay_value>>28)&0xf, ! 4061: (ssleay_value>>20)&0xff, ! 4062: (ssleay_value>>12)&0xff, ! 4063: sub); ! 4064: #endif /* OPENSSL_IS_BORINGSSL */ ! 4065: } ! 4066: ! 4067: /* can be called with data == NULL */ ! 4068: static CURLcode Curl_ossl_random(struct Curl_easy *data, ! 4069: unsigned char *entropy, size_t length) ! 4070: { ! 4071: int rc; ! 4072: if(data) { ! 4073: if(Curl_ossl_seed(data)) /* Initiate the seed if not already done */ ! 4074: return CURLE_FAILED_INIT; /* couldn't seed for some reason */ ! 4075: } ! 4076: else { ! 4077: if(!rand_enough()) ! 4078: return CURLE_FAILED_INIT; ! 4079: } ! 4080: /* RAND_bytes() returns 1 on success, 0 otherwise. */ ! 4081: rc = RAND_bytes(entropy, curlx_uztosi(length)); ! 4082: return (rc == 1 ? CURLE_OK : CURLE_FAILED_INIT); ! 4083: } ! 4084: ! 4085: static CURLcode Curl_ossl_md5sum(unsigned char *tmp, /* input */ ! 4086: size_t tmplen, ! 4087: unsigned char *md5sum /* output */, ! 4088: size_t unused) ! 4089: { ! 4090: EVP_MD_CTX *mdctx; ! 4091: unsigned int len = 0; ! 4092: (void) unused; ! 4093: ! 4094: mdctx = EVP_MD_CTX_create(); ! 4095: EVP_DigestInit_ex(mdctx, EVP_md5(), NULL); ! 4096: EVP_DigestUpdate(mdctx, tmp, tmplen); ! 4097: EVP_DigestFinal_ex(mdctx, md5sum, &len); ! 4098: EVP_MD_CTX_destroy(mdctx); ! 4099: return CURLE_OK; ! 4100: } ! 4101: ! 4102: #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) ! 4103: static CURLcode Curl_ossl_sha256sum(const unsigned char *tmp, /* input */ ! 4104: size_t tmplen, ! 4105: unsigned char *sha256sum /* output */, ! 4106: size_t unused) ! 4107: { ! 4108: EVP_MD_CTX *mdctx; ! 4109: unsigned int len = 0; ! 4110: (void) unused; ! 4111: ! 4112: mdctx = EVP_MD_CTX_create(); ! 4113: EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL); ! 4114: EVP_DigestUpdate(mdctx, tmp, tmplen); ! 4115: EVP_DigestFinal_ex(mdctx, sha256sum, &len); ! 4116: EVP_MD_CTX_destroy(mdctx); ! 4117: return CURLE_OK; ! 4118: } ! 4119: #endif ! 4120: ! 4121: static bool Curl_ossl_cert_status_request(void) ! 4122: { ! 4123: #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ ! 4124: !defined(OPENSSL_NO_OCSP) ! 4125: return TRUE; ! 4126: #else ! 4127: return FALSE; ! 4128: #endif ! 4129: } ! 4130: ! 4131: static void *Curl_ossl_get_internals(struct ssl_connect_data *connssl, ! 4132: CURLINFO info) ! 4133: { ! 4134: /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ ! 4135: struct ssl_backend_data *backend = connssl->backend; ! 4136: return info == CURLINFO_TLS_SESSION ? ! 4137: (void *)backend->ctx : (void *)backend->handle; ! 4138: } ! 4139: ! 4140: const struct Curl_ssl Curl_ssl_openssl = { ! 4141: { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */ ! 4142: ! 4143: SSLSUPP_CA_PATH | ! 4144: SSLSUPP_CERTINFO | ! 4145: SSLSUPP_PINNEDPUBKEY | ! 4146: SSLSUPP_SSL_CTX | ! 4147: #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES ! 4148: SSLSUPP_TLS13_CIPHERSUITES | ! 4149: #endif ! 4150: SSLSUPP_HTTPS_PROXY, ! 4151: ! 4152: sizeof(struct ssl_backend_data), ! 4153: ! 4154: Curl_ossl_init, /* init */ ! 4155: Curl_ossl_cleanup, /* cleanup */ ! 4156: Curl_ossl_version, /* version */ ! 4157: Curl_ossl_check_cxn, /* check_cxn */ ! 4158: Curl_ossl_shutdown, /* shutdown */ ! 4159: Curl_ossl_data_pending, /* data_pending */ ! 4160: Curl_ossl_random, /* random */ ! 4161: Curl_ossl_cert_status_request, /* cert_status_request */ ! 4162: Curl_ossl_connect, /* connect */ ! 4163: Curl_ossl_connect_nonblocking, /* connect_nonblocking */ ! 4164: Curl_ossl_get_internals, /* get_internals */ ! 4165: Curl_ossl_close, /* close_one */ ! 4166: Curl_ossl_close_all, /* close_all */ ! 4167: Curl_ossl_session_free, /* session_free */ ! 4168: Curl_ossl_set_engine, /* set_engine */ ! 4169: Curl_ossl_set_engine_default, /* set_engine_default */ ! 4170: Curl_ossl_engines_list, /* engines_list */ ! 4171: Curl_none_false_start, /* false_start */ ! 4172: Curl_ossl_md5sum, /* md5sum */ ! 4173: #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) ! 4174: Curl_ossl_sha256sum /* sha256sum */ ! 4175: #else ! 4176: NULL /* sha256sum */ ! 4177: #endif ! 4178: }; ! 4179: ! 4180: #endif /* USE_OPENSSL */