diff --git a/lib/url.c b/lib/url.c index de43df4f7b..adef2cdb36 100644 --- a/lib/url.c +++ b/lib/url.c @@ -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 diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c index a4d2d910b6..77e22cf3e0 100644 --- a/lib/vtls/bearssl.c +++ b/lib/vtls/bearssl.c @@ -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); diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c index 00449efd1d..56d48497db 100644 --- a/lib/vtls/gskit.c +++ b/lib/vtls/gskit.c @@ -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; } diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index f9ef4d12b4..57493767e5 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -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; } diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index d79be3d9be..b9fd26acca 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -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; } diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c index c3f40f2b96..558e3bed39 100644 --- a/lib/vtls/nss.c +++ b/lib/vtls/nss.c @@ -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; } diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index eaf7028f00..fc35f784da 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -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) diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c index 1c4cb19104..0e651aed9d 100644 --- a/lib/vtls/rustls.c +++ b/lib/vtls/rustls.c @@ -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); diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index ae36630e74..04c8f3b6cf 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -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; } diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c index 01de3fc732..202a814cd9 100644 --- a/lib/vtls/schannel_verify.c +++ b/lib/vtls/schannel_verify.c @@ -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, diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c index be41d4f4bb..b2e1727278 100644 --- a/lib/vtls/sectransp.c +++ b/lib/vtls/sectransp.c @@ -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; } diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index 41714d54b2..bf7a9a1e92 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -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); diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c index 1dbf5ecbb5..eae5568309 100644 --- a/lib/vtls/wolfssl.c +++ b/lib/vtls/wolfssl.c @@ -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; }