openssl: remove the BACKEND define kludge

Use a proper variable instead to make it easier to use a debugger and
read the code.
This commit is contained in:
Daniel Stenberg 2020-03-18 16:58:38 +01:00
Родитель 3c9066fce5
Коммит aec0b49df3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
1 изменённых файлов: 113 добавлений и 107 удалений

Просмотреть файл

@ -228,8 +228,6 @@ struct ssl_backend_data {
#endif #endif
}; };
#define BACKEND connssl->backend
/* /*
* Number of bytes to read from the random number seed file. This must be * Number of bytes to read from the random number seed file. This must be
* a finite value (because some entropy "files" like /dev/urandom have * a finite value (because some entropy "files" like /dev/urandom have
@ -1269,19 +1267,19 @@ static struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data)
return list; return list;
} }
static void ossl_close(struct ssl_connect_data *connssl) static void ossl_close(struct ssl_connect_data *connssl)
{ {
if(BACKEND->handle) { struct ssl_backend_data *backend = connssl->backend;
(void)SSL_shutdown(BACKEND->handle); if(backend->handle) {
SSL_set_connect_state(BACKEND->handle); (void)SSL_shutdown(backend->handle);
SSL_set_connect_state(backend->handle);
SSL_free(BACKEND->handle); SSL_free(backend->handle);
BACKEND->handle = NULL; backend->handle = NULL;
} }
if(BACKEND->ctx) { if(backend->ctx) {
SSL_CTX_free(BACKEND->ctx); SSL_CTX_free(backend->ctx);
BACKEND->ctx = NULL; backend->ctx = NULL;
} }
} }
@ -1310,6 +1308,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
int buffsize; int buffsize;
int err; int err;
bool done = FALSE; bool done = FALSE;
struct ssl_backend_data *backend = connssl->backend;
#ifndef CURL_DISABLE_FTP #ifndef CURL_DISABLE_FTP
/* This has only been tested on the proftpd server, and the mod_tls code /* This has only been tested on the proftpd server, and the mod_tls code
@ -1318,10 +1317,10 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
we do not send one. Let's hope other servers do the same... */ we do not send one. Let's hope other servers do the same... */
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
(void)SSL_shutdown(BACKEND->handle); (void)SSL_shutdown(backend->handle);
#endif #endif
if(BACKEND->handle) { if(backend->handle) {
buffsize = (int)sizeof(buf); buffsize = (int)sizeof(buf);
while(!done) { while(!done) {
int what = SOCKET_READABLE(conn->sock[sockindex], int what = SOCKET_READABLE(conn->sock[sockindex],
@ -1331,8 +1330,8 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
/* Something to read, let's do it and hope that it is the close /* Something to read, let's do it and hope that it is the close
notify alert from the server */ notify alert from the server */
nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize); nread = (ssize_t)SSL_read(backend->handle, buf, buffsize);
err = SSL_get_error(BACKEND->handle, (int)nread); err = SSL_get_error(backend->handle, (int)nread);
switch(err) { switch(err) {
case SSL_ERROR_NONE: /* this is not an error */ case SSL_ERROR_NONE: /* this is not an error */
@ -1377,7 +1376,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
if(data->set.verbose) { if(data->set.verbose) {
#ifdef HAVE_SSL_GET_SHUTDOWN #ifdef HAVE_SSL_GET_SHUTDOWN
switch(SSL_get_shutdown(BACKEND->handle)) { switch(SSL_get_shutdown(backend->handle)) {
case SSL_SENT_SHUTDOWN: case SSL_SENT_SHUTDOWN:
infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n"); infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
break; break;
@ -1392,8 +1391,8 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
#endif #endif
} }
SSL_free(BACKEND->handle); SSL_free(backend->handle);
BACKEND->handle = NULL; backend->handle = NULL;
} }
return retval; return retval;
} }
@ -1712,13 +1711,13 @@ static CURLcode verifystatus(struct connectdata *conn,
const unsigned char *p; const unsigned char *p;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data; struct Curl_easy *data = conn->data;
OCSP_RESPONSE *rsp = NULL; OCSP_RESPONSE *rsp = NULL;
OCSP_BASICRESP *br = NULL; OCSP_BASICRESP *br = NULL;
X509_STORE *st = NULL; X509_STORE *st = NULL;
STACK_OF(X509) *ch = NULL; STACK_OF(X509) *ch = NULL;
struct ssl_backend_data *backend = connssl->backend;
long len = SSL_get_tlsext_status_ocsp_resp(BACKEND->handle, &status); long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
if(!status) { if(!status) {
failf(data, "No OCSP response received"); failf(data, "No OCSP response received");
@ -1748,8 +1747,8 @@ static CURLcode verifystatus(struct connectdata *conn,
goto end; goto end;
} }
ch = SSL_get_peer_cert_chain(BACKEND->handle); ch = SSL_get_peer_cert_chain(backend->handle);
st = SSL_CTX_get_cert_store(BACKEND->ctx); st = SSL_CTX_get_cert_store(backend->ctx);
#if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \ #if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
(defined(LIBRESSL_VERSION_NUMBER) && \ (defined(LIBRESSL_VERSION_NUMBER) && \
@ -2270,7 +2269,7 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
#ifdef TLS1_3_VERSION #ifdef TLS1_3_VERSION
{ {
struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex];
SSL_CTX_set_max_proto_version(BACKEND->ctx, TLS1_3_VERSION); SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
*ctx_options |= SSL_OP_NO_TLSv1_2; *ctx_options |= SSL_OP_NO_TLSv1_2;
} }
#else #else
@ -2419,6 +2418,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
char error_buffer[256]; char error_buffer[256];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state); DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
@ -2477,25 +2477,25 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
} }
if(BACKEND->ctx) if(backend->ctx)
SSL_CTX_free(BACKEND->ctx); SSL_CTX_free(backend->ctx);
BACKEND->ctx = SSL_CTX_new(req_method); backend->ctx = SSL_CTX_new(req_method);
if(!BACKEND->ctx) { if(!backend->ctx) {
failf(data, "SSL: couldn't create a context: %s", failf(data, "SSL: couldn't create a context: %s",
ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer))); ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer)));
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
#ifdef SSL_MODE_RELEASE_BUFFERS #ifdef SSL_MODE_RELEASE_BUFFERS
SSL_CTX_set_mode(BACKEND->ctx, SSL_MODE_RELEASE_BUFFERS); SSL_CTX_set_mode(backend->ctx, SSL_MODE_RELEASE_BUFFERS);
#endif #endif
#ifdef SSL_CTRL_SET_MSG_CALLBACK #ifdef SSL_CTRL_SET_MSG_CALLBACK
if(data->set.fdebug && data->set.verbose) { if(data->set.fdebug && data->set.verbose) {
/* the SSL trace callback is only used for verbose logging */ /* the SSL trace callback is only used for verbose logging */
SSL_CTX_set_msg_callback(BACKEND->ctx, ssl_tls_trace); SSL_CTX_set_msg_callback(backend->ctx, ssl_tls_trace);
SSL_CTX_set_msg_callback_arg(BACKEND->ctx, conn); SSL_CTX_set_msg_callback_arg(backend->ctx, conn);
} }
#endif #endif
@ -2561,8 +2561,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
/* "--sslv2" option means SSLv2 only, disable all others */ /* "--sslv2" option means SSLv2 only, disable all others */
case CURL_SSLVERSION_SSLv2: case CURL_SSLVERSION_SSLv2:
#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
SSL_CTX_set_min_proto_version(BACKEND->ctx, SSL2_VERSION); SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION);
SSL_CTX_set_max_proto_version(BACKEND->ctx, SSL2_VERSION); SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION);
#else #else
ctx_options |= SSL_OP_NO_SSLv3; ctx_options |= SSL_OP_NO_SSLv3;
ctx_options |= SSL_OP_NO_TLSv1; ctx_options |= SSL_OP_NO_TLSv1;
@ -2579,8 +2579,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
/* "--sslv3" option means SSLv3 only, disable all others */ /* "--sslv3" option means SSLv3 only, disable all others */
case CURL_SSLVERSION_SSLv3: case CURL_SSLVERSION_SSLv3:
#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */
SSL_CTX_set_min_proto_version(BACKEND->ctx, SSL3_VERSION); SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION);
SSL_CTX_set_max_proto_version(BACKEND->ctx, SSL3_VERSION); SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION);
#else #else
ctx_options |= SSL_OP_NO_SSLv2; ctx_options |= SSL_OP_NO_SSLv2;
ctx_options |= SSL_OP_NO_TLSv1; ctx_options |= SSL_OP_NO_TLSv1;
@ -2607,7 +2607,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
ctx_options |= SSL_OP_NO_SSLv3; ctx_options |= SSL_OP_NO_SSLv3;
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
result = set_ssl_version_min_max(BACKEND->ctx, conn); result = set_ssl_version_min_max(backend->ctx, conn);
#else #else
result = set_ssl_version_min_max_legacy(&ctx_options, conn, sockindex); result = set_ssl_version_min_max_legacy(&ctx_options, conn, sockindex);
#endif #endif
@ -2620,11 +2620,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
return CURLE_SSL_CONNECT_ERROR; return CURLE_SSL_CONNECT_ERROR;
} }
SSL_CTX_set_options(BACKEND->ctx, ctx_options); SSL_CTX_set_options(backend->ctx, ctx_options);
#ifdef HAS_NPN #ifdef HAS_NPN
if(conn->bits.tls_enable_npn) if(conn->bits.tls_enable_npn)
SSL_CTX_set_next_proto_select_cb(BACKEND->ctx, select_next_proto_cb, conn); SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, conn);
#endif #endif
#ifdef HAS_ALPN #ifdef HAS_ALPN
@ -2652,12 +2652,12 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
/* expects length prefixed preference ordered list of protocols in wire /* expects length prefixed preference ordered list of protocols in wire
* format * format
*/ */
SSL_CTX_set_alpn_protos(BACKEND->ctx, protocols, cur); SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur);
} }
#endif #endif
if(ssl_cert || ssl_cert_type) { if(ssl_cert || ssl_cert_type) {
if(!cert_stuff(conn, BACKEND->ctx, ssl_cert, ssl_cert_type, if(!cert_stuff(conn, backend->ctx, ssl_cert, ssl_cert_type,
SSL_SET_OPTION(key), SSL_SET_OPTION(key_type), SSL_SET_OPTION(key), SSL_SET_OPTION(key_type),
SSL_SET_OPTION(key_passwd))) { SSL_SET_OPTION(key_passwd))) {
/* failf() is already done in cert_stuff() */ /* failf() is already done in cert_stuff() */
@ -2669,7 +2669,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
if(!ciphers) if(!ciphers)
ciphers = (char *)DEFAULT_CIPHER_SELECTION; ciphers = (char *)DEFAULT_CIPHER_SELECTION;
if(ciphers) { if(ciphers) {
if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) { if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
failf(data, "failed setting cipher list: %s", ciphers); failf(data, "failed setting cipher list: %s", ciphers);
return CURLE_SSL_CIPHER; return CURLE_SSL_CIPHER;
} }
@ -2680,7 +2680,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
{ {
char *ciphers13 = SSL_CONN_CONFIG(cipher_list13); char *ciphers13 = SSL_CONN_CONFIG(cipher_list13);
if(ciphers13) { if(ciphers13) {
if(!SSL_CTX_set_ciphersuites(BACKEND->ctx, ciphers13)) { if(!SSL_CTX_set_ciphersuites(backend->ctx, ciphers13)) {
failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13); failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13);
return CURLE_SSL_CIPHER; return CURLE_SSL_CIPHER;
} }
@ -2691,7 +2691,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
/* OpenSSL 1.1.1 requires clients to opt-in for PHA */ /* OpenSSL 1.1.1 requires clients to opt-in for PHA */
SSL_CTX_set_post_handshake_auth(BACKEND->ctx, 1); SSL_CTX_set_post_handshake_auth(backend->ctx, 1);
#endif #endif
#ifdef USE_TLS_SRP #ifdef USE_TLS_SRP
@ -2700,18 +2700,18 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
infof(data, "Using TLS-SRP username: %s\n", ssl_username); infof(data, "Using TLS-SRP username: %s\n", ssl_username);
if(!SSL_CTX_set_srp_username(BACKEND->ctx, ssl_username)) { if(!SSL_CTX_set_srp_username(backend->ctx, ssl_username)) {
failf(data, "Unable to set SRP user name"); failf(data, "Unable to set SRP user name");
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
} }
if(!SSL_CTX_set_srp_password(BACKEND->ctx, SSL_SET_OPTION(password))) { if(!SSL_CTX_set_srp_password(backend->ctx, SSL_SET_OPTION(password))) {
failf(data, "failed setting SRP password"); failf(data, "failed setting SRP password");
return CURLE_BAD_FUNCTION_ARGUMENT; return CURLE_BAD_FUNCTION_ARGUMENT;
} }
if(!SSL_CONN_CONFIG(cipher_list)) { if(!SSL_CONN_CONFIG(cipher_list)) {
infof(data, "Setting cipher list SRP\n"); infof(data, "Setting cipher list SRP\n");
if(!SSL_CTX_set_cipher_list(BACKEND->ctx, "SRP")) { if(!SSL_CTX_set_cipher_list(backend->ctx, "SRP")) {
failf(data, "failed setting SRP cipher list"); failf(data, "failed setting SRP cipher list");
return CURLE_SSL_CIPHER; return CURLE_SSL_CIPHER;
} }
@ -2722,7 +2722,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
if(ssl_cafile || ssl_capath) { if(ssl_cafile || ssl_capath) {
/* tell SSL where to find CA certificates that are used to verify /* tell SSL where to find CA certificates that are used to verify
the servers certificate. */ the servers certificate. */
if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) { if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) {
if(verifypeer) { if(verifypeer) {
/* Fail if we insist on successfully verifying the server. */ /* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate verify locations:\n" failf(data, "error setting certificate verify locations:\n"
@ -2750,14 +2750,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
else if(verifypeer) { else if(verifypeer) {
/* verifying the peer without any CA certificates won't /* verifying the peer without any CA certificates won't
work so use openssl's built in default as fallback */ work so use openssl's built in default as fallback */
SSL_CTX_set_default_verify_paths(BACKEND->ctx); SSL_CTX_set_default_verify_paths(backend->ctx);
} }
#endif #endif
if(ssl_crlfile) { if(ssl_crlfile) {
/* tell SSL where to find CRL file that is used to check certificate /* tell SSL where to find CRL file that is used to check certificate
* revocation */ * revocation */
lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(BACKEND->ctx), lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(backend->ctx),
X509_LOOKUP_file()); X509_LOOKUP_file());
if(!lookup || if(!lookup ||
(!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) { (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) {
@ -2766,7 +2766,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
} }
/* Everything is fine. */ /* Everything is fine. */
infof(data, "successfully load CRL file:\n"); infof(data, "successfully load CRL file:\n");
X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
infof(data, " CRLfile: %s\n", ssl_crlfile); infof(data, " CRLfile: %s\n", ssl_crlfile);
@ -2781,7 +2781,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
*/ */
#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) #if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
X509_V_FLAG_TRUSTED_FIRST); X509_V_FLAG_TRUSTED_FIRST);
#endif #endif
#ifdef X509_V_FLAG_PARTIAL_CHAIN #ifdef X509_V_FLAG_PARTIAL_CHAIN
@ -2790,7 +2790,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
trust-anchors, in the same way as self-signed root CA certificates trust-anchors, in the same way as self-signed root CA certificates
are. This allows users to verify servers using the intermediate cert are. This allows users to verify servers using the intermediate cert
only, instead of needing the whole chain. */ only, instead of needing the whole chain. */
X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx),
X509_V_FLAG_PARTIAL_CHAIN); X509_V_FLAG_PARTIAL_CHAIN);
} }
#endif #endif
@ -2800,13 +2800,13 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
* fail to connect if the verification fails, or if it should continue * fail to connect if the verification fails, or if it should continue
* anyway. In the latter case the result of the verification is checked with * anyway. In the latter case the result of the verification is checked with
* SSL_get_verify_result() below. */ * SSL_get_verify_result() below. */
SSL_CTX_set_verify(BACKEND->ctx, SSL_CTX_set_verify(backend->ctx,
verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
/* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */
#if defined(ENABLE_SSLKEYLOGFILE) && defined(HAVE_KEYLOG_CALLBACK) #if defined(ENABLE_SSLKEYLOGFILE) && defined(HAVE_KEYLOG_CALLBACK)
if(keylog_file_fp) { if(keylog_file_fp) {
SSL_CTX_set_keylog_callback(BACKEND->ctx, ossl_keylog_callback); SSL_CTX_set_keylog_callback(backend->ctx, ossl_keylog_callback);
} }
#endif #endif
@ -2814,14 +2814,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
* callback. Use the "external storage" mode to avoid that OpenSSL creates * callback. Use the "external storage" mode to avoid that OpenSSL creates
* an internal session cache. * an internal session cache.
*/ */
SSL_CTX_set_session_cache_mode(BACKEND->ctx, SSL_CTX_set_session_cache_mode(backend->ctx,
SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
SSL_CTX_sess_set_new_cb(BACKEND->ctx, ossl_new_session_cb); SSL_CTX_sess_set_new_cb(backend->ctx, ossl_new_session_cb);
/* give application a chance to interfere with SSL set up. */ /* give application a chance to interfere with SSL set up. */
if(data->set.ssl.fsslctx) { if(data->set.ssl.fsslctx) {
Curl_set_in_callback(data, true); Curl_set_in_callback(data, true);
result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx, result = (*data->set.ssl.fsslctx)(data, backend->ctx,
data->set.ssl.fsslctxp); data->set.ssl.fsslctxp);
Curl_set_in_callback(data, false); Curl_set_in_callback(data, false);
if(result) { if(result) {
@ -2831,10 +2831,10 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
} }
/* Lets make an SSL structure */ /* Lets make an SSL structure */
if(BACKEND->handle) if(backend->handle)
SSL_free(BACKEND->handle); SSL_free(backend->handle);
BACKEND->handle = SSL_new(BACKEND->ctx); backend->handle = SSL_new(backend->ctx);
if(!BACKEND->handle) { if(!backend->handle) {
failf(data, "SSL: couldn't create a context (handle)!"); failf(data, "SSL: couldn't create a context (handle)!");
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
@ -2842,23 +2842,23 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
!defined(OPENSSL_NO_OCSP) !defined(OPENSSL_NO_OCSP)
if(SSL_CONN_CONFIG(verifystatus)) if(SSL_CONN_CONFIG(verifystatus))
SSL_set_tlsext_status_type(BACKEND->handle, TLSEXT_STATUSTYPE_ocsp); SSL_set_tlsext_status_type(backend->handle, TLSEXT_STATUSTYPE_ocsp);
#endif #endif
#if defined(OPENSSL_IS_BORINGSSL) && defined(ALLOW_RENEG) #if defined(OPENSSL_IS_BORINGSSL) && defined(ALLOW_RENEG)
SSL_set_renegotiate_mode(BACKEND->handle, ssl_renegotiate_freely); SSL_set_renegotiate_mode(backend->handle, ssl_renegotiate_freely);
#endif #endif
SSL_set_connect_state(BACKEND->handle); SSL_set_connect_state(backend->handle);
BACKEND->server_cert = 0x0; backend->server_cert = 0x0;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) && if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
(0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
#endif #endif
sni && sni &&
!SSL_set_tlsext_host_name(BACKEND->handle, hostname)) !SSL_set_tlsext_host_name(backend->handle, hostname))
infof(data, "WARNING: failed to configure server name indication (SNI) " infof(data, "WARNING: failed to configure server name indication (SNI) "
"TLS extension\n"); "TLS extension\n");
#endif #endif
@ -2872,14 +2872,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
if(connectdata_idx >= 0 && sockindex_idx >= 0) { if(connectdata_idx >= 0 && sockindex_idx >= 0) {
/* Store the data needed for the "new session" callback. /* Store the data needed for the "new session" callback.
* The sockindex is stored as a pointer to an array element. */ * The sockindex is stored as a pointer to an array element. */
SSL_set_ex_data(BACKEND->handle, connectdata_idx, conn); SSL_set_ex_data(backend->handle, connectdata_idx, conn);
SSL_set_ex_data(BACKEND->handle, sockindex_idx, conn->sock + sockindex); SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex);
} }
Curl_ssl_sessionid_lock(conn); Curl_ssl_sessionid_lock(conn);
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
/* we got a session id, use it! */ /* we got a session id, use it! */
if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) { if(!SSL_set_session(backend->handle, ssl_sessionid)) {
Curl_ssl_sessionid_unlock(conn); Curl_ssl_sessionid_unlock(conn);
failf(data, "SSL: SSL_set_session failed: %s", failf(data, "SSL: SSL_set_session failed: %s",
ossl_strerror(ERR_get_error(), error_buffer, ossl_strerror(ERR_get_error(), error_buffer,
@ -2899,9 +2899,9 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
DEBUGASSERT(handle != NULL); DEBUGASSERT(handle != NULL);
DEBUGASSERT(bio != NULL); DEBUGASSERT(bio != NULL);
BIO_set_ssl(bio, handle, FALSE); BIO_set_ssl(bio, handle, FALSE);
SSL_set_bio(BACKEND->handle, bio, bio); SSL_set_bio(backend->handle, bio, bio);
} }
else if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) { else if(!SSL_set_fd(backend->handle, (int)sockfd)) {
/* pass the raw socket into the SSL layers */ /* pass the raw socket into the SSL layers */
failf(data, "SSL: SSL_set_fd failed: %s", failf(data, "SSL: SSL_set_fd failed: %s",
ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer))); ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)));
@ -2920,24 +2920,25 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex];
long * const certverifyresult = SSL_IS_PROXY() ? long * const certverifyresult = SSL_IS_PROXY() ?
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state
|| ssl_connect_2_writing == connssl->connecting_state); || ssl_connect_2_writing == connssl->connecting_state);
ERR_clear_error(); ERR_clear_error();
err = SSL_connect(BACKEND->handle); err = SSL_connect(backend->handle);
/* If keylogging is enabled but the keylog callback is not supported then log /* If keylogging is enabled but the keylog callback is not supported then log
secrets here, immediately after SSL_connect by using tap_ssl_key. */ secrets here, immediately after SSL_connect by using tap_ssl_key. */
#if defined(ENABLE_SSLKEYLOGFILE) && !defined(HAVE_KEYLOG_CALLBACK) #if defined(ENABLE_SSLKEYLOGFILE) && !defined(HAVE_KEYLOG_CALLBACK)
tap_ssl_key(BACKEND->handle, &BACKEND->tap_state); tap_ssl_key(backend->handle, &backend->tap_state);
#endif #endif
/* 1 is fine /* 1 is fine
0 is "not successful but was shut down controlled" 0 is "not successful but was shut down controlled"
<0 is "handshake was not successful, because a fatal error occurred" */ <0 is "handshake was not successful, because a fatal error occurred" */
if(1 != err) { if(1 != err) {
int detail = SSL_get_error(BACKEND->handle, err); int detail = SSL_get_error(backend->handle, err);
if(SSL_ERROR_WANT_READ == detail) { if(SSL_ERROR_WANT_READ == detail) {
connssl->connecting_state = ssl_connect_2_reading; connssl->connecting_state = ssl_connect_2_reading;
@ -2977,7 +2978,7 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
(reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) { (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
result = CURLE_PEER_FAILED_VERIFICATION; result = CURLE_PEER_FAILED_VERIFICATION;
lerr = SSL_get_verify_result(BACKEND->handle); lerr = SSL_get_verify_result(backend->handle);
if(lerr != X509_V_OK) { if(lerr != X509_V_OK) {
*certverifyresult = lerr; *certverifyresult = lerr;
msnprintf(error_buffer, sizeof(error_buffer), msnprintf(error_buffer, sizeof(error_buffer),
@ -3026,8 +3027,8 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
/* Informational message */ /* Informational message */
infof(data, "SSL connection using %s / %s\n", infof(data, "SSL connection using %s / %s\n",
get_ssl_version_txt(BACKEND->handle), get_ssl_version_txt(backend->handle),
SSL_get_cipher(BACKEND->handle)); SSL_get_cipher(backend->handle));
#ifdef HAS_ALPN #ifdef HAS_ALPN
/* Sets data and len to negotiated protocol, len is 0 if no protocol was /* Sets data and len to negotiated protocol, len is 0 if no protocol was
@ -3036,7 +3037,7 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
if(conn->bits.tls_enable_alpn) { if(conn->bits.tls_enable_alpn) {
const unsigned char *neg_protocol; const unsigned char *neg_protocol;
unsigned int len; unsigned int len;
SSL_get0_alpn_selected(BACKEND->handle, &neg_protocol, &len); SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len);
if(len != 0) { if(len != 0) {
infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol); infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol);
@ -3171,8 +3172,9 @@ static CURLcode get_cert_chain(struct connectdata *conn,
struct Curl_easy *data = conn->data; struct Curl_easy *data = conn->data;
numcert_t numcerts; numcert_t numcerts;
BIO *mem; BIO *mem;
struct ssl_backend_data *backend = connssl->backend;
sk = SSL_get_peer_cert_chain(BACKEND->handle); sk = SSL_get_peer_cert_chain(backend->handle);
if(!sk) { if(!sk) {
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
@ -3458,13 +3460,14 @@ static CURLcode servercert(struct connectdata *conn,
long * const certverifyresult = SSL_IS_PROXY() ? long * const certverifyresult = SSL_IS_PROXY() ?
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
BIO *mem = BIO_new(BIO_s_mem()); BIO *mem = BIO_new(BIO_s_mem());
struct ssl_backend_data *backend = connssl->backend;
if(data->set.ssl.certinfo) if(data->set.ssl.certinfo)
/* we've been asked to gather certificate info! */ /* we've been asked to gather certificate info! */
(void)get_cert_chain(conn, connssl); (void)get_cert_chain(conn, connssl);
BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle); backend->server_cert = SSL_get_peer_certificate(backend->handle);
if(!BACKEND->server_cert) { if(!backend->server_cert) {
BIO_free(mem); BIO_free(mem);
if(!strict) if(!strict)
return CURLE_OK; return CURLE_OK;
@ -3475,19 +3478,19 @@ static CURLcode servercert(struct connectdata *conn,
infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server"); infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server");
rc = x509_name_oneline(X509_get_subject_name(BACKEND->server_cert), rc = x509_name_oneline(X509_get_subject_name(backend->server_cert),
buffer, sizeof(buffer)); buffer, sizeof(buffer));
infof(data, " subject: %s\n", rc?"[NONE]":buffer); infof(data, " subject: %s\n", rc?"[NONE]":buffer);
#ifndef CURL_DISABLE_VERBOSE_STRINGS #ifndef CURL_DISABLE_VERBOSE_STRINGS
{ {
long len; long len;
ASN1_TIME_print(mem, X509_get0_notBefore(BACKEND->server_cert)); ASN1_TIME_print(mem, X509_get0_notBefore(backend->server_cert));
len = BIO_get_mem_data(mem, (char **) &ptr); len = BIO_get_mem_data(mem, (char **) &ptr);
infof(data, " start date: %.*s\n", len, ptr); infof(data, " start date: %.*s\n", len, ptr);
(void)BIO_reset(mem); (void)BIO_reset(mem);
ASN1_TIME_print(mem, X509_get0_notAfter(BACKEND->server_cert)); ASN1_TIME_print(mem, X509_get0_notAfter(backend->server_cert));
len = BIO_get_mem_data(mem, (char **) &ptr); len = BIO_get_mem_data(mem, (char **) &ptr);
infof(data, " expire date: %.*s\n", len, ptr); infof(data, " expire date: %.*s\n", len, ptr);
(void)BIO_reset(mem); (void)BIO_reset(mem);
@ -3497,15 +3500,15 @@ static CURLcode servercert(struct connectdata *conn,
BIO_free(mem); BIO_free(mem);
if(SSL_CONN_CONFIG(verifyhost)) { if(SSL_CONN_CONFIG(verifyhost)) {
result = verifyhost(conn, BACKEND->server_cert); result = verifyhost(conn, backend->server_cert);
if(result) { if(result) {
X509_free(BACKEND->server_cert); X509_free(backend->server_cert);
BACKEND->server_cert = NULL; backend->server_cert = NULL;
return result; return result;
} }
} }
rc = x509_name_oneline(X509_get_issuer_name(BACKEND->server_cert), rc = x509_name_oneline(X509_get_issuer_name(backend->server_cert),
buffer, sizeof(buffer)); buffer, sizeof(buffer));
if(rc) { if(rc) {
if(strict) if(strict)
@ -3527,8 +3530,8 @@ static CURLcode servercert(struct connectdata *conn,
" error %s", " error %s",
ossl_strerror(ERR_get_error(), error_buffer, ossl_strerror(ERR_get_error(), error_buffer,
sizeof(error_buffer)) ); sizeof(error_buffer)) );
X509_free(BACKEND->server_cert); X509_free(backend->server_cert);
BACKEND->server_cert = NULL; backend->server_cert = NULL;
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
@ -3537,8 +3540,8 @@ static CURLcode servercert(struct connectdata *conn,
failf(data, "SSL: Unable to open issuer cert (%s)", failf(data, "SSL: Unable to open issuer cert (%s)",
SSL_SET_OPTION(issuercert)); SSL_SET_OPTION(issuercert));
BIO_free(fp); BIO_free(fp);
X509_free(BACKEND->server_cert); X509_free(backend->server_cert);
BACKEND->server_cert = NULL; backend->server_cert = NULL;
return CURLE_SSL_ISSUER_ERROR; return CURLE_SSL_ISSUER_ERROR;
} }
@ -3549,19 +3552,19 @@ static CURLcode servercert(struct connectdata *conn,
SSL_SET_OPTION(issuercert)); SSL_SET_OPTION(issuercert));
BIO_free(fp); BIO_free(fp);
X509_free(issuer); X509_free(issuer);
X509_free(BACKEND->server_cert); X509_free(backend->server_cert);
BACKEND->server_cert = NULL; backend->server_cert = NULL;
return CURLE_SSL_ISSUER_ERROR; return CURLE_SSL_ISSUER_ERROR;
} }
if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) { if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) {
if(strict) if(strict)
failf(data, "SSL: Certificate issuer check failed (%s)", failf(data, "SSL: Certificate issuer check failed (%s)",
SSL_SET_OPTION(issuercert)); SSL_SET_OPTION(issuercert));
BIO_free(fp); BIO_free(fp);
X509_free(issuer); X509_free(issuer);
X509_free(BACKEND->server_cert); X509_free(backend->server_cert);
BACKEND->server_cert = NULL; backend->server_cert = NULL;
return CURLE_SSL_ISSUER_ERROR; return CURLE_SSL_ISSUER_ERROR;
} }
@ -3571,7 +3574,7 @@ static CURLcode servercert(struct connectdata *conn,
X509_free(issuer); X509_free(issuer);
} }
lerr = *certverifyresult = SSL_get_verify_result(BACKEND->handle); lerr = *certverifyresult = SSL_get_verify_result(backend->handle);
if(*certverifyresult != X509_V_OK) { if(*certverifyresult != X509_V_OK) {
if(SSL_CONN_CONFIG(verifypeer)) { if(SSL_CONN_CONFIG(verifypeer)) {
@ -3596,8 +3599,8 @@ static CURLcode servercert(struct connectdata *conn,
if(SSL_CONN_CONFIG(verifystatus)) { if(SSL_CONN_CONFIG(verifystatus)) {
result = verifystatus(conn, connssl); result = verifystatus(conn, connssl);
if(result) { if(result) {
X509_free(BACKEND->server_cert); X509_free(backend->server_cert);
BACKEND->server_cert = NULL; backend->server_cert = NULL;
return result; return result;
} }
} }
@ -3610,13 +3613,13 @@ static CURLcode servercert(struct connectdata *conn,
ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
if(!result && ptr) { if(!result && ptr) {
result = pkp_pin_peer_pubkey(data, BACKEND->server_cert, ptr); result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
if(result) if(result)
failf(data, "SSL: public key does not match pinned public key!"); failf(data, "SSL: public key does not match pinned public key!");
} }
X509_free(BACKEND->server_cert); X509_free(backend->server_cert);
BACKEND->server_cert = NULL; backend->server_cert = NULL;
connssl->connecting_state = ssl_connect_done; connssl->connecting_state = ssl_connect_done;
return result; return result;
@ -3810,14 +3813,15 @@ static ssize_t ossl_send(struct connectdata *conn,
int memlen; int memlen;
int rc; int rc;
struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
ERR_clear_error(); ERR_clear_error();
memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
rc = SSL_write(BACKEND->handle, mem, memlen); rc = SSL_write(backend->handle, mem, memlen);
if(rc <= 0) { if(rc <= 0) {
err = SSL_get_error(BACKEND->handle, rc); err = SSL_get_error(backend->handle, rc);
switch(err) { switch(err) {
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
@ -3884,14 +3888,15 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
ssize_t nread; ssize_t nread;
int buffsize; int buffsize;
struct ssl_connect_data *connssl = &conn->ssl[num]; struct ssl_connect_data *connssl = &conn->ssl[num];
struct ssl_backend_data *backend = connssl->backend;
ERR_clear_error(); ERR_clear_error();
buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize); nread = (ssize_t)SSL_read(backend->handle, buf, buffsize);
if(nread <= 0) { if(nread <= 0) {
/* failed SSL_read */ /* failed SSL_read */
int err = SSL_get_error(BACKEND->handle, (int)nread); int err = SSL_get_error(backend->handle, (int)nread);
switch(err) { switch(err) {
case SSL_ERROR_NONE: /* this is not an error */ case SSL_ERROR_NONE: /* this is not an error */
@ -4097,8 +4102,9 @@ static void *Curl_ossl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info) CURLINFO info)
{ {
/* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
struct ssl_backend_data *backend = connssl->backend;
return info == CURLINFO_TLS_SESSION ? return info == CURLINFO_TLS_SESSION ?
(void *)BACKEND->ctx : (void *)BACKEND->handle; (void *)backend->ctx : (void *)backend->handle;
} }
const struct Curl_ssl Curl_ssl_openssl = { const struct Curl_ssl Curl_ssl_openssl = {