Annotation of embedaddon/curl/lib/vtls/openssl.c, revision 1.1
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 */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>