ssl: reduce allocated space for ssl backend when FTP is disabled

Add assert() for the backend pointer in many places

Closes #8471
This commit is contained in:
MAntoniak 2022-02-17 17:48:48 +01:00 committed by Daniel Stenberg
parent 9fff7feb82
commit ccc2752ce8
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
13 changed files with 267 additions and 35 deletions

View File

@ -136,15 +136,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "curl_memory.h"
#include "memdebug.h"
/* Count of the backend ssl objects to allocate */
#ifdef USE_SSL
# ifndef CURL_DISABLE_PROXY
# define SSL_BACKEND_CNT 4
# else
# define SSL_BACKEND_CNT 2
# endif
#endif
static void conn_free(struct connectdata *conn);
/* Some parts of the code (e.g. chunked encoding) assume this buffer has at
@ -752,7 +743,9 @@ static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn)
/* close the SSL stuff before we close any sockets since they will/may
write to the sockets */
Curl_ssl_close(data, conn, FIRSTSOCKET);
#ifndef CURL_DISABLE_FTP
Curl_ssl_close(data, conn, SECONDARYSOCKET);
#endif
/* close possibly still open sockets */
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
@ -1667,18 +1660,35 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
Note that these backend pointers can be swapped by vtls (eg ssl backend
data becomes proxy backend data). */
{
size_t sslsize = Curl_ssl->sizeof_ssl_backend_data;
char *ssl = calloc(SSL_BACKEND_CNT, sslsize);
size_t onesize = Curl_ssl->sizeof_ssl_backend_data;
size_t totalsize = onesize;
char *ssl;
#ifndef CURL_DISABLE_FTP
totalsize *= 2;
#endif
#ifndef CURL_DISABLE_PROXY
totalsize *= 2;
#endif
ssl = calloc(1, totalsize);
if(!ssl) {
free(conn);
return NULL;
}
conn->ssl_extra = ssl;
conn->ssl[0].backend = (void *)ssl;
conn->ssl[1].backend = (void *)(ssl + sslsize);
conn->ssl[FIRSTSOCKET].backend = (void *)ssl;
#ifndef CURL_DISABLE_FTP
ssl += onesize;
conn->ssl[SECONDARYSOCKET].backend = (void *)ssl;
#endif
#ifndef CURL_DISABLE_PROXY
conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize);
conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize);
ssl += onesize;
conn->proxy_ssl[FIRSTSOCKET].backend = (void *)ssl;
#ifndef CURL_DISABLE_FTP
ssl += onesize;
conn->proxy_ssl[SECONDARYSOCKET].backend = (void *)ssl;
#endif
#endif
}
#endif

View File

@ -373,6 +373,8 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
struct in_addr addr;
#endif
DEBUGASSERT(backend);
switch(SSL_CONN_CONFIG(version)) {
case CURL_SSLVERSION_SSLv2:
failf(data, "BearSSL does not support SSLv2");
@ -530,6 +532,8 @@ static CURLcode bearssl_run_until(struct Curl_easy *data,
ssize_t ret;
int err;
DEBUGASSERT(backend);
for(;;) {
state = br_ssl_engine_current_state(&backend->ctx.eng);
if(state & BR_SSL_CLOSED) {
@ -602,6 +606,8 @@ static CURLcode bearssl_connect_step2(struct Curl_easy *data,
struct ssl_backend_data *backend = connssl->backend;
CURLcode ret;
DEBUGASSERT(backend);
ret = bearssl_run_until(data, conn, sockindex,
BR_SSL_SENDAPP | BR_SSL_RECVAPP);
if(ret == CURLE_AGAIN)
@ -624,6 +630,7 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data,
CURLcode ret;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
if(conn->bits.tls_enable_alpn) {
const char *protocol;
@ -689,6 +696,8 @@ static ssize_t bearssl_send(struct Curl_easy *data, int sockindex,
unsigned char *app;
size_t applen;
DEBUGASSERT(backend);
for(;;) {
*err = bearssl_run_until(data, conn, sockindex, BR_SSL_SENDAPP);
if (*err != CURLE_OK)
@ -722,6 +731,8 @@ static ssize_t bearssl_recv(struct Curl_easy *data, int sockindex,
unsigned char *app;
size_t applen;
DEBUGASSERT(backend);
*err = bearssl_run_until(data, conn, sockindex, BR_SSL_RECVAPP);
if(*err != CURLE_OK)
return -1;
@ -847,6 +858,7 @@ static bool bearssl_data_pending(const struct connectdata *conn,
{
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
}
@ -896,6 +908,7 @@ static void *bearssl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
return &backend->ctx;
}
@ -906,6 +919,8 @@ static void bearssl_close(struct Curl_easy *data,
struct ssl_backend_data *backend = connssl->backend;
size_t i;
DEBUGASSERT(backend);
if(backend->active) {
br_ssl_engine_close(&backend->ctx.eng);
(void)bearssl_run_until(data, conn, sockindex, BR_SSL_CLOSED);

View File

@ -514,6 +514,8 @@ static void cancel_async_handshake(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
Qso_OverlappedIO_t cstat;
DEBUGASSERT(BACKEND);
if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
QsoWaitForIOCompletion(BACKEND->iocport, &cstat, (struct timeval *) NULL);
}
@ -521,6 +523,7 @@ static void cancel_async_handshake(struct connectdata *conn, int sockindex)
static void close_async_handshake(struct ssl_connect_data *connssl)
{
DEBUGASSERT(BACKEND);
QsoDestroyIOCompletionPort(BACKEND->iocport);
BACKEND->iocport = -1;
}
@ -538,6 +541,9 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
int ret = 0;
char buf[CURL_MAX_WRITE_SIZE];
DEBUGASSERT(BACKEND);
DEBUGASSERT(connproxyssl->backend);
if(!connssl->use || !connproxyssl->use)
return 0; /* No SSL over SSL: OK. */
@ -602,6 +608,7 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data,
struct connectdata *conn, int sockindex)
{
DEBUGASSERT(BACKEND);
if(BACKEND->handle) {
gskit_status(data, gsk_secure_soc_close(&BACKEND->handle),
"gsk_secure_soc_close()", 0);
@ -633,6 +640,8 @@ static ssize_t gskit_send(struct Curl_easy *data, int sockindex,
CURLcode cc = CURLE_SEND_ERROR;
int written;
DEBUGASSERT(BACKEND);
if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) >= 0) {
cc = gskit_status(data,
gsk_secure_soc_write(BACKEND->handle,
@ -658,6 +667,8 @@ static ssize_t gskit_recv(struct Curl_easy *data, int num, char *buf,
int nread;
CURLcode cc = CURLE_RECV_ERROR;
DEBUGASSERT(BACKEND);
if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) {
int buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
cc = gskit_status(data, gsk_secure_soc_read(BACKEND->handle,
@ -731,6 +742,7 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
#endif
/* Create SSL environment, start (preferably asynchronous) handshake. */
DEBUGASSERT(BACKEND);
BACKEND->handle = (gsk_handle) NULL;
BACKEND->iocport = -1;
@ -960,6 +972,7 @@ static CURLcode gskit_connect_step2(struct Curl_easy *data,
CURLcode result;
/* Poll or wait for end of SSL asynchronous handshake. */
DEBUGASSERT(BACKEND);
for(;;) {
timediff_t timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
@ -1016,6 +1029,7 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data,
CURLcode result;
/* SSL handshake done: gather certificate info and verify host. */
DEBUGASSERT(BACKEND);
if(gskit_status(data, gsk_attribute_get_cert_info(BACKEND->handle,
GSK_PARTNER_CERT_INFO,
@ -1208,6 +1222,8 @@ static int gskit_shutdown(struct Curl_easy *data,
char buf[120];
int loop = 10; /* don't get stuck */
DEBUGASSERT(BACKEND);
if(!BACKEND->handle)
return 0;
@ -1271,6 +1287,7 @@ static int gskit_check_cxn(struct connectdata *cxn)
int errlen;
/* The only thing that can be tested here is at the socket level. */
DEBUGASSERT(BACKEND);
if(!BACKEND->handle)
return 0; /* connection has been closed */
@ -1290,6 +1307,7 @@ static void *gskit_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
(void)info;
DEBUGASSERT(BACKEND);
return BACKEND->handle;
}

View File

@ -202,9 +202,12 @@ static CURLcode handshake(struct Curl_easy *data,
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
gnutls_session_t session = backend->session;
gnutls_session_t session;
curl_socket_t sockfd = conn->sock[sockindex];
DEBUGASSERT(backend);
session = backend->session;
for(;;) {
timediff_t timeout_ms;
int rc;
@ -406,6 +409,8 @@ gtls_connect_step1(struct Curl_easy *data,
const char *tls13support;
CURLcode result;
DEBUGASSERT(backend);
if(connssl->state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
same connection */
@ -701,7 +706,10 @@ gtls_connect_step1(struct Curl_easy *data,
#ifndef CURL_DISABLE_PROXY
if(conn->proxy_ssl[sockindex].use) {
transport_ptr = conn->proxy_ssl[sockindex].backend->session;
struct ssl_backend_data *proxy_backend;
proxy_backend = conn->proxy_ssl[sockindex].backend;
DEBUGASSERT(proxy_backend);
transport_ptr = proxy_backend->session;
gnutls_transport_push = gtls_push_ssl;
gnutls_transport_pull = gtls_pull_ssl;
}
@ -1356,7 +1364,9 @@ gtls_connect_common(struct Curl_easy *data,
/* Finish connecting once the handshake is done */
if(ssl_connect_1 == connssl->connecting_state) {
struct ssl_backend_data *backend = connssl->backend;
gnutls_session_t session = backend->session;
gnutls_session_t session;
DEBUGASSERT(backend);
session = backend->session;
rc = Curl_gtls_verifyserver(data, conn, session, sockindex);
if(rc)
return rc;
@ -1397,6 +1407,9 @@ static bool gtls_data_pending(const struct connectdata *conn,
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
bool res = FALSE;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
if(backend->session &&
0 != gnutls_record_check_pending(backend->session))
res = TRUE;
@ -1404,6 +1417,7 @@ static bool gtls_data_pending(const struct connectdata *conn,
#ifndef CURL_DISABLE_PROXY
connssl = &conn->proxy_ssl[connindex];
backend = connssl->backend;
DEBUGASSERT(backend);
if(backend->session &&
0 != gnutls_record_check_pending(backend->session))
res = TRUE;
@ -1421,7 +1435,10 @@ static ssize_t gtls_send(struct Curl_easy *data,
struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
ssize_t rc = gnutls_record_send(backend->session, mem, len);
ssize_t rc;
DEBUGASSERT(backend);
rc = gnutls_record_send(backend->session, mem, len);
if(rc < 0) {
*curlcode = (rc == GNUTLS_E_AGAIN)
@ -1437,6 +1454,8 @@ static ssize_t gtls_send(struct Curl_easy *data,
static void close_one(struct ssl_connect_data *connssl)
{
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
if(backend->session) {
char buf[32];
/* Maybe the server has already sent a close notify alert.
@ -1479,6 +1498,8 @@ static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn,
struct ssl_backend_data *backend = connssl->backend;
int retval = 0;
DEBUGASSERT(backend);
#ifndef CURL_DISABLE_FTP
/* This has only been tested on the proftpd server, and the mod_tls code
sends a close notify alert without waiting for a close notify alert in
@ -1557,6 +1578,8 @@ static ssize_t gtls_recv(struct Curl_easy *data, /* connection data */
struct ssl_backend_data *backend = connssl->backend;
ssize_t ret;
DEBUGASSERT(backend);
ret = gnutls_record_recv(backend->session, buf, buffersize);
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
*curlcode = CURLE_AGAIN;
@ -1628,6 +1651,7 @@ static void *gtls_get_internals(struct ssl_connect_data *connssl,
{
struct ssl_backend_data *backend = connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->session;
}

View File

@ -230,6 +230,8 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
long ssl_version_max = SSL_CONN_CONFIG(version_max);
CURLcode result = CURLE_OK;
DEBUGASSERT(backend);
switch(ssl_version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
@ -285,6 +287,8 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
int ret = -1;
char errorbuf[128];
DEBUGASSERT(backend);
if((SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) ||
(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)) {
failf(data, "Not supported SSL version");
@ -665,6 +669,8 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
const mbedtls_x509_crt *peercert;
const char * const pinnedpubkey = SSL_PINNED_PUB_KEY();
DEBUGASSERT(backend);
conn->recv[sockindex] = mbed_recv;
conn->send[sockindex] = mbed_send;
@ -844,6 +850,7 @@ mbed_connect_step3(struct Curl_easy *data, struct connectdata *conn,
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
if(SSL_SET_OPTION(primary.sessionid)) {
int ret;
@ -900,6 +907,8 @@ static ssize_t mbed_send(struct Curl_easy *data, int sockindex,
struct ssl_backend_data *backend = connssl->backend;
int ret = -1;
DEBUGASSERT(backend);
ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len);
if(ret < 0) {
@ -924,6 +933,8 @@ static void mbedtls_close(struct Curl_easy *data,
char buf[32];
(void) data;
DEBUGASSERT(backend);
/* Maybe the server has already sent a close notify alert.
Read it to avoid an RST on the TCP connection. */
(void)mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, sizeof(buf));
@ -952,6 +963,8 @@ static ssize_t mbed_recv(struct Curl_easy *data, int num,
int ret = -1;
ssize_t len = -1;
DEBUGASSERT(backend);
ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf,
buffersize);
@ -1186,6 +1199,7 @@ static bool mbedtls_data_pending(const struct connectdata *conn,
{
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0;
}
@ -1215,6 +1229,7 @@ static void *mbedtls_get_internals(struct ssl_connect_data *connssl,
{
struct ssl_backend_data *backend = connssl->backend;
(void)info;
DEBUGASSERT(backend);
return &backend->ssl;
}

View File

@ -488,6 +488,9 @@ static CURLcode nss_create_object(struct ssl_connect_data *connssl,
const int slot_id = (cacert) ? 0 : 1;
char *slot_name = aprintf("PEM Token #%d", slot_id);
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
if(!slot_name)
return CURLE_OUT_OF_MEMORY;
@ -1111,9 +1114,12 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
{
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
struct ssl_backend_data *backend = connssl->backend;
struct Curl_easy *data = backend->data;
struct Curl_easy *data = NULL;
CERTCertificate *cert;
DEBUGASSERT(backend);
data = backend->data;
if(!pinnedpubkey)
/* no pinned public key specified */
return CURLE_OK;
@ -1164,10 +1170,15 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
{
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
struct ssl_backend_data *backend = connssl->backend;
struct Curl_easy *data = backend->data;
const char *nickname = backend->client_nickname;
struct Curl_easy *data = NULL;
const char *nickname = NULL;
static const char pem_slotname[] = "PEM Token #1";
DEBUGASSERT(backend);
data = backend->data;
nickname = backend->client_nickname;
if(backend->obj_clicert) {
/* use the cert/key provided by PEM reader */
SECItem cert_der = { 0, NULL, 0 };
@ -1535,6 +1546,8 @@ static int nss_check_cxn(struct connectdata *conn)
int rc;
char buf;
DEBUGASSERT(backend);
rc =
PR_Recv(backend->handle, (void *)&buf, 1, PR_MSG_PEEK,
PR_SecondsToInterval(1));
@ -1551,7 +1564,11 @@ static void close_one(struct ssl_connect_data *connssl)
{
/* before the cleanup, check whether we are using a client certificate */
struct ssl_backend_data *backend = connssl->backend;
const bool client_cert = (backend->client_nickname != NULL)
bool client_cert = true;
DEBUGASSERT(backend);
client_cert = (backend->client_nickname != NULL)
|| (backend->obj_clicert != NULL);
if(backend->handle) {
@ -1593,8 +1610,13 @@ static void nss_close(struct Curl_easy *data, struct connectdata *conn,
struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
#endif
struct ssl_backend_data *backend = connssl->backend;
(void)data;
DEBUGASSERT(backend);
#ifndef CURL_DISABLE_PROXY
DEBUGASSERT(connssl_proxy->backend != NULL);
#endif
if(backend->handle
#ifndef CURL_DISABLE_PROXY
|| connssl_proxy->backend->handle
@ -1822,6 +1844,8 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
{
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
if(is_nss_error(curlerr)) {
/* read NSPR error code */
PRErrorCode err = PR_GetError();
@ -1848,6 +1872,9 @@ static CURLcode nss_set_blocking(struct ssl_connect_data *connssl,
{
PRSocketOptionData sock_opt;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
sock_opt.option = PR_SockOpt_Nonblocking;
sock_opt.value.non_blocking = !blocking;
@ -1889,6 +1916,8 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
return CURLE_SSL_CONNECT_ERROR;
}
DEBUGASSERT(backend);
backend->data = data;
/* list of all NSS objects we need to destroy in nss_do_close() */
@ -2038,9 +2067,12 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
#ifndef CURL_DISABLE_PROXY
if(conn->proxy_ssl[sockindex].use) {
struct ssl_backend_data *proxy_backend;
proxy_backend = conn->proxy_ssl[sockindex].backend;
DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
DEBUGASSERT(conn->proxy_ssl[sockindex].backend->handle != NULL);
nspr_io = conn->proxy_ssl[sockindex].backend->handle;
DEBUGASSERT(proxy_backend);
DEBUGASSERT(proxy_backend->handle);
nspr_io = proxy_backend->handle;
second_layer = TRUE;
}
#endif
@ -2182,6 +2214,8 @@ static CURLcode nss_do_connect(struct Curl_easy *data,
goto error;
}
DEBUGASSERT(backend);
/* Force the handshake now */
timeout = PR_MillisecondsToInterval((PRUint32) time_left);
if(SSL_ForceHandshakeWithTimeout(backend->handle, timeout) != SECSuccess) {
@ -2315,6 +2349,8 @@ static ssize_t nss_send(struct Curl_easy *data, /* transfer */
struct ssl_backend_data *backend = connssl->backend;
ssize_t rc;
DEBUGASSERT(backend);
/* The SelectClientCert() hook uses this for infof() and failf() but the
handle stored in nss_setup_connect() could have already been freed. */
backend->data = data;
@ -2354,6 +2390,8 @@ static ssize_t nss_recv(struct Curl_easy *data, /* transfer */
struct ssl_backend_data *backend = connssl->backend;
ssize_t nread;
DEBUGASSERT(backend);
/* The SelectClientCert() hook uses this for infof() and failf() but the
handle stored in nss_setup_connect() could have already been freed. */
backend->data = data;
@ -2452,6 +2490,7 @@ static void *nss_get_internals(struct ssl_connect_data *connssl,
{
struct ssl_backend_data *backend = connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->handle;
}

View File

@ -1431,6 +1431,9 @@ static void ossl_closeone(struct Curl_easy *data,
struct ssl_connect_data *connssl)
{
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
if(backend->handle) {
char buf[32];
set_logger(conn, data);
@ -1488,6 +1491,8 @@ static int ossl_shutdown(struct Curl_easy *data,
struct ssl_backend_data *backend = connssl->backend;
int loop = 10;
DEBUGASSERT(backend);
#ifndef CURL_DISABLE_FTP
/* This has only been tested on the proftpd server, and the mod_tls code
sends a close notify alert without waiting for a close notify alert in
@ -1861,8 +1866,11 @@ static CURLcode verifystatus(struct Curl_easy *data,
int cert_status, crl_reason;
ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
int ret;
long len;
long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
DEBUGASSERT(backend);
len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
if(!status) {
failf(data, "No OCSP response received");
@ -2121,7 +2129,10 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
struct connectdata *conn = userp;
struct ssl_connect_data *connssl = &conn->ssl[0];
struct ssl_backend_data *backend = connssl->backend;
struct Curl_easy *data = backend->logger;
struct Curl_easy *data = NULL;
DEBUGASSERT(backend);
data = backend->logger;
if(!conn || !data || !data->set.fdebug ||
(direction != 0 && direction != 1))
@ -2410,6 +2421,7 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
*ctx_options |= SSL_OP_NO_TLSv1_2;
}
@ -2637,6 +2649,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
bool imported_native_ca = false;
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
DEBUGASSERT(backend);
/* Make funny stuff to get random input */
result = ossl_seed(data);
@ -3245,7 +3258,11 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#ifndef CURL_DISABLE_PROXY
if(conn->proxy_ssl[sockindex].use) {
BIO *const bio = BIO_new(BIO_f_ssl());
SSL *handle = conn->proxy_ssl[sockindex].backend->handle;
struct ssl_backend_data *proxy_backend;
SSL* handle = NULL;
proxy_backend = conn->proxy_ssl[sockindex].backend;
DEBUGASSERT(proxy_backend);
handle = proxy_backend->handle;
DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
DEBUGASSERT(handle != NULL);
DEBUGASSERT(bio != NULL);
@ -3275,6 +3292,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
|| ssl_connect_2_writing == connssl->connecting_state);
DEBUGASSERT(backend);
ERR_clear_error();
@ -3536,6 +3554,8 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
BIO *mem;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
sk = SSL_get_peer_cert_chain(backend->handle);
if(!sk) {
return CURLE_OUT_OF_MEMORY;
@ -3848,6 +3868,8 @@ static CURLcode servercert(struct Curl_easy *data,
BIO *mem = BIO_new(BIO_s_mem());
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
if(!mem) {
failf(data,
"BIO_new return NULL, " OSSL_PACKAGE
@ -4198,11 +4220,13 @@ static bool ossl_data_pending(const struct connectdata *conn,
int connindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
DEBUGASSERT(connssl->backend);
if(connssl->backend->handle && SSL_pending(connssl->backend->handle))
return TRUE;
#ifndef CURL_DISABLE_PROXY
{
const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex];
DEBUGASSERT(proxyssl->backend);
if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle))
return TRUE;
}
@ -4229,6 +4253,8 @@ static ssize_t ossl_send(struct Curl_easy *data,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
ERR_clear_error();
memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
@ -4308,6 +4334,8 @@ static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
struct ssl_connect_data *connssl = &conn->ssl[num];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
ERR_clear_error();
buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
@ -4507,6 +4535,7 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl,
{
/* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
return info == CURLINFO_TLS_SESSION ?
(void *)backend->ctx : (void *)backend->handle;
}
@ -4517,6 +4546,7 @@ static bool ossl_associate_connection(struct Curl_easy *data,
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
/* If we don't have SSL context, do nothing. */
if(!backend->handle)
@ -4566,6 +4596,7 @@ static void ossl_disassociate_connection(struct Curl_easy *data,
struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
/* If we don't have SSL context, do nothing. */
if(!backend->handle)

View File

@ -65,6 +65,7 @@ cr_data_pending(const struct connectdata *conn, int sockindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
return backend->data_pending;
}
@ -118,7 +119,8 @@ cr_recv(struct Curl_easy *data, int sockindex,
struct connectdata *conn = data->conn;
struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
struct ssl_backend_data *const backend = connssl->backend;
struct rustls_connection *const rconn = backend->conn;
struct rustls_connection *rconn = NULL;
size_t n = 0;
size_t tls_bytes_read = 0;
size_t plain_bytes_copied = 0;
@ -126,6 +128,9 @@ cr_recv(struct Curl_easy *data, int sockindex,
char errorbuf[255];
rustls_io_result io_error;
DEBUGASSERT(backend);
rconn = backend->conn;
io_error = rustls_connection_read_tls(rconn, read_cb,
&conn->sock[sockindex], &tls_bytes_read);
if(io_error == EAGAIN || io_error == EWOULDBLOCK) {
@ -215,13 +220,16 @@ cr_send(struct Curl_easy *data, int sockindex,
struct connectdata *conn = data->conn;
struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
struct ssl_backend_data *const backend = connssl->backend;
struct rustls_connection *const rconn = backend->conn;
struct rustls_connection *rconn = NULL;
size_t plainwritten = 0;
size_t tlswritten = 0;
size_t tlswritten_total = 0;
rustls_result rresult;
rustls_io_result io_error;
DEBUGASSERT(backend);
rconn = backend->conn;
infof(data, "cr_send %ld bytes of plaintext", plainlen);
if(plainlen > 0) {
@ -295,7 +303,7 @@ static CURLcode
cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
struct ssl_backend_data *const backend)
{
struct rustls_connection *rconn = backend->conn;
struct rustls_connection *rconn = NULL;
struct rustls_client_config_builder *config_builder = NULL;
struct rustls_root_cert_store *roots = NULL;
const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
@ -312,6 +320,9 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
{ (const uint8_t *)ALPN_H2, ALPN_H2_LENGTH },
};
DEBUGASSERT(backend);
rconn = backend->conn;
config_builder = rustls_client_config_builder_new();
#ifdef USE_HTTP2
infof(data, "offering ALPN for HTTP/1.1 and HTTP/2");
@ -435,6 +446,8 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t writefd;
curl_socket_t readfd;
DEBUGASSERT(backend);
if(ssl_connection_none == connssl->state) {
result = cr_init_backend(data, conn, connssl->backend);
if(result != CURLE_OK) {
@ -529,7 +542,10 @@ cr_getsock(struct connectdata *conn, curl_socket_t *socks)
struct ssl_connect_data *const connssl = &conn->ssl[FIRSTSOCKET];
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
struct ssl_backend_data *const backend = connssl->backend;
struct rustls_connection *rconn = backend->conn;
struct rustls_connection *rconn = NULL;
DEBUGASSERT(backend);
rconn = backend->conn;
if(rustls_connection_wants_write(rconn)) {
socks[0] = sockfd;
@ -548,6 +564,7 @@ cr_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
return &backend->conn;
}
@ -560,6 +577,8 @@ cr_close(struct Curl_easy *data, struct connectdata *conn,
CURLcode tmperr = CURLE_OK;
ssize_t n = 0;
DEBUGASSERT(backend);
if(backend->conn) {
rustls_connection_send_close_notify(backend->conn);
n = cr_send(data, sockindex, NULL, 0, &tmperr);

View File

@ -426,6 +426,8 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
CURLcode result;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
/* setup Schannel API options */
memset(&schannel_cred, 0, sizeof(schannel_cred));
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
@ -772,6 +774,8 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
char * const hostname = SSL_HOST_NAME();
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
DEBUGF(infof(data,
"schannel: SSL/TLS connection with %s port %hu (step 1/3)",
hostname, conn->remote_port));
@ -1038,6 +1042,8 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
const char *pubkey_ptr;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
DEBUGF(infof(data,
@ -1371,6 +1377,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
DEBUGF(infof(data,
"schannel: SSL/TLS connection with %s port %hu (step 3/3)",
@ -1611,6 +1618,7 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
*/
{
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
conn->sslContext = &backend->ctxt->ctxt_handle;
}
#endif
@ -1641,6 +1649,8 @@ schannel_send(struct Curl_easy *data, int sockindex,
CURLcode result;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
/* check if the maximum stream sizes were queried */
if(backend->stream_sizes.cbMaximumMessage == 0) {
sspi_status = s_pSecFn->QueryContextAttributes(
@ -1789,6 +1799,8 @@ schannel_recv(struct Curl_easy *data, int sockindex,
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
/****************************************************************************
* Don't return or set backend->recv_unrecoverable_err unless in the cleanup.
* The pattern for return error is set *err, optional infof, goto cleanup.
@ -2123,6 +2135,8 @@ static bool schannel_data_pending(const struct connectdata *conn,
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
if(connssl->use) /* SSL/TLS is in use */
return (backend->decdata_offset > 0 ||
(backend->encdata_offset > 0 && !backend->encdata_is_incomplete));
@ -2159,6 +2173,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(data);
DEBUGASSERT(backend);
if(connssl->use) {
infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu",
@ -2309,6 +2324,8 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
/* Result is returned to caller */
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
DEBUGASSERT(backend);
/* if a path wasn't specified, don't pin */
if(!pinnedpubkey)
return CURLE_OK;
@ -2429,6 +2446,7 @@ static void *schannel_get_internals(struct ssl_connect_data *connssl,
{
struct ssl_backend_data *backend = connssl->backend;
(void)info;
DEBUGASSERT(backend);
return &backend->ctxt->ctxt_handle;
}

View File

@ -576,6 +576,8 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
HCERTSTORE trust_store = NULL;
const char * const conn_hostname = SSL_HOST_NAME();
DEBUGASSERT(BACKEND);
sspi_status =
s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,

View File

@ -837,12 +837,14 @@ static OSStatus SocketRead(SSLConnectionRef connection,
/*int sock = *(int *)connection;*/
struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
struct ssl_backend_data *backend = connssl->backend;
int sock = backend->ssl_sockfd;
int sock;
OSStatus rtn = noErr;
size_t bytesRead;
ssize_t rrtn;
int theErr;
DEBUGASSERT(backend);
sock = backend->ssl_sockfd;
*dataLength = 0;
for(;;) {
@ -898,13 +900,15 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
/*int sock = *(int *)connection;*/
struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
struct ssl_backend_data *backend = connssl->backend;
int sock = backend->ssl_sockfd;
int sock;
ssize_t length;
size_t dataLen = *dataLength;
const UInt8 *dataPtr = (UInt8 *)data;
OSStatus ortn;
int theErr;
DEBUGASSERT(backend);
sock = backend->ssl_sockfd;
*dataLength = 0;
do {
@ -1376,6 +1380,8 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
long ssl_version_max = SSL_CONN_CONFIG(version_max);
long max_supported_version_by_os;
DEBUGASSERT(backend);
/* macOS 10.5-10.7 supported TLS 1.0 only.
macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
@ -1684,6 +1690,8 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#if CURL_BUILD_MAC
int darwinver_maj = 0, darwinver_min = 0;
DEBUGASSERT(backend);
GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
#endif /* CURL_BUILD_MAC */
@ -2547,6 +2555,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
|| ssl_connect_2_writing == connssl->connecting_state);
DEBUGASSERT(backend);
/* Here goes nothing: */
err = SSLHandshake(backend->ssl_ctx);
@ -2923,6 +2932,8 @@ collect_server_cert(struct Curl_easy *data,
CFIndex i, count;
SecTrustRef trust = NULL;
DEBUGASSERT(backend);
if(!show_verbose_server_cert && !data->set.ssl.certinfo)
return CURLE_OK;
@ -3167,6 +3178,8 @@ static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
(void) data;
DEBUGASSERT(backend);
if(backend->ssl_ctx) {
(void)SSLClose(backend->ssl_ctx);
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
@ -3195,6 +3208,8 @@ static int sectransp_shutdown(struct Curl_easy *data,
char buf[120];
int loop = 10; /* avoid getting stuck */
DEBUGASSERT(backend);
if(!backend->ssl_ctx)
return 0;
@ -3274,6 +3289,8 @@ static int sectransp_check_cxn(struct connectdata *conn)
OSStatus err;
SSLSessionState state;
DEBUGASSERT(backend);
if(backend->ssl_ctx) {
err = SSLGetSessionState(backend->ssl_ctx, &state);
if(err == noErr)
@ -3291,6 +3308,8 @@ static bool sectransp_data_pending(const struct connectdata *conn,
OSStatus err;
size_t buffer;
DEBUGASSERT(backend);
if(backend->ssl_ctx) { /* SSL is in use */
err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer);
if(err == noErr)
@ -3352,6 +3371,8 @@ static ssize_t sectransp_send(struct Curl_easy *data,
size_t processed = 0UL;
OSStatus err;
DEBUGASSERT(backend);
/* The SSLWrite() function works a little differently than expected. The
fourth argument (processed) is currently documented in Apple's
documentation as: "On return, the length, in bytes, of the data actually
@ -3419,6 +3440,8 @@ static ssize_t sectransp_recv(struct Curl_easy *data,
size_t processed = 0UL;
OSStatus err;
DEBUGASSERT(backend);
again:
err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed);
@ -3468,6 +3491,7 @@ static void *sectransp_get_internals(struct ssl_connect_data *connssl,
{
struct ssl_backend_data *backend = connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->ssl_ctx;
}

View File

@ -300,6 +300,8 @@ ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
pbdata = conn->proxy_ssl[sockindex].backend;
conn->proxy_ssl[sockindex] = conn->ssl[sockindex];
DEBUGASSERT(pbdata != NULL);
memset(&conn->ssl[sockindex], 0, sizeof(conn->ssl[sockindex]));
memset(pbdata, 0, Curl_ssl->sizeof_ssl_backend_data);

View File

@ -263,6 +263,8 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#define use_sni(x) Curl_nop_stmt
#endif
DEBUGASSERT(backend);
if(connssl->state == ssl_connection_complete)
return CURLE_OK;
@ -598,6 +600,8 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
const char * const dispname = SSL_HOST_DISPNAME();
const char * const pinnedpubkey = SSL_PINNED_PUB_KEY();
DEBUGASSERT(backend);
ERR_clear_error();
conn->recv[sockindex] = wolfssl_recv;
@ -802,6 +806,7 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn,
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
if(SSL_SET_OPTION(primary.sessionid)) {
bool incache;
@ -853,6 +858,8 @@ static ssize_t wolfssl_send(struct Curl_easy *data,
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
int rc;
DEBUGASSERT(backend);
ERR_clear_error();
rc = SSL_write(backend->handle, mem, memlen);
@ -885,6 +892,8 @@ static void wolfssl_close(struct Curl_easy *data, struct connectdata *conn,
(void) data;
DEBUGASSERT(backend);
if(backend->handle) {
char buf[32];
/* Maybe the server has already sent a close notify alert.
@ -913,6 +922,8 @@ static ssize_t wolfssl_recv(struct Curl_easy *data,
int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
int nread;
DEBUGASSERT(backend);
ERR_clear_error();
nread = SSL_read(backend->handle, buf, buffsize);
@ -982,6 +993,7 @@ static bool wolfssl_data_pending(const struct connectdata *conn,
{
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(backend);
if(backend->handle) /* SSL is in use */
return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE;
else
@ -1002,6 +1014,8 @@ static int wolfssl_shutdown(struct Curl_easy *data, struct connectdata *conn,
(void) data;
DEBUGASSERT(backend);
if(backend->handle) {
ERR_clear_error();
SSL_free(backend->handle);
@ -1181,6 +1195,7 @@ static void *wolfssl_get_internals(struct ssl_connect_data *connssl,
{
struct ssl_backend_data *backend = connssl->backend;
(void)info;
DEBUGASSERT(backend);
return backend->handle;
}