diff options
Diffstat (limited to 'Utilities/cmcurl/lib/vtls/gskit.c')
-rw-r--r-- | Utilities/cmcurl/lib/vtls/gskit.c | 79 |
1 files changed, 51 insertions, 28 deletions
diff --git a/Utilities/cmcurl/lib/vtls/gskit.c b/Utilities/cmcurl/lib/vtls/gskit.c index e451f6a..9b5fbe4 100644 --- a/Utilities/cmcurl/lib/vtls/gskit.c +++ b/Utilities/cmcurl/lib/vtls/gskit.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -28,6 +28,7 @@ #include <qsoasync.h> #undef HAVE_SOCKETPAIR /* because the native one isn't good enough */ #include "socketpair.h" +#include "strerror.h" /* Some symbols are undefined/unsupported on OS400 versions < V7R1. */ #ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST @@ -73,6 +74,7 @@ #include "connect.h" /* for the connect timeout */ #include "select.h" #include "strcase.h" +#include "timediff.h" #include "x509asn1.h" #include "curl_printf.h" @@ -247,10 +249,10 @@ static CURLcode set_enum(struct Curl_easy *data, gsk_handle h, static CURLcode set_buffer(struct Curl_easy *data, gsk_handle h, - GSK_BUF_ID id, const char *buffer, bool unsupported_ok) + GSK_BUF_ID id, const char *buf, bool unsupported_ok) { char buffer[STRERROR_LEN]; - int rc = gsk_attribute_set_buffer(h, id, buffer, 0); + int rc = gsk_attribute_set_buffer(h, id, buf, 0); switch(rc) { case GSK_OK: @@ -448,8 +450,7 @@ static CURLcode set_ciphers(struct Curl_easy *data, static int gskit_init(void) { - /* No initialisation needed. */ - + /* No initialization needed. */ return 1; } @@ -513,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); } @@ -520,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; } @@ -530,36 +534,36 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex, #ifndef CURL_DISABLE_PROXY struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex]; - fd_set fds_read; - fd_set fds_write; + struct pollfd fds[2]; int n; int m; int i; 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. */ - FD_ZERO(&fds_read); - FD_ZERO(&fds_write); - n = -1; + n = 1; + fds[0].fd = BACKEND->remotefd; + fds[1].fd = conn->sock[sockindex]; + if(directions & SOS_READ) { - FD_SET(BACKEND->remotefd, &fds_write); - n = BACKEND->remotefd; + fds[0].events |= POLLOUT; } if(directions & SOS_WRITE) { - FD_SET(BACKEND->remotefd, &fds_read); - n = BACKEND->remotefd; - FD_SET(conn->sock[sockindex], &fds_write); - if(n < conn->sock[sockindex]) - n = conn->sock[sockindex]; + n = 2; + fds[0].events |= POLLIN; + fds[1].events |= POLLOUT; } - i = Curl_select(n + 1, &fds_read, &fds_write, NULL, 0); + i = Curl_poll(fds, n, 0); if(i < 0) return -1; /* Select error. */ - if(FD_ISSET(BACKEND->remotefd, &fds_write)) { + if(fds[0].revents & POLLOUT) { /* Try getting data from HTTPS proxy and pipe it upstream. */ n = 0; i = gsk_secure_soc_read(connproxyssl->backend->handle, @@ -581,8 +585,7 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex, } } - if(FD_ISSET(BACKEND->remotefd, &fds_read) && - FD_ISSET(conn->sock[sockindex], &fds_write)) { + if((fds[0].revents & POLLIN) && (fds[1].revents & POLLOUT)) { /* Pipe data to HTTPS proxy. */ n = read(BACKEND->remotefd, buf, sizeof(buf)); if(n < 0) @@ -605,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); @@ -636,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, @@ -661,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, @@ -734,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; @@ -830,8 +839,13 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, /* Process SNI. Ignore if not supported (on OS400 < V7R1). */ if(sni) { + char *snihost = Curl_ssl_snihost(data, sni, NULL); + if(!snihost) { + failf(data, "Failed to set SNI"); + return CURLE_SSL_CONNECT_ERROR; + } result = set_buffer(data, BACKEND->handle, - GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE); + GSK_SSL_EXTN_SERVERNAME_REQUEST, snihost, TRUE); if(result == CURLE_UNSUPPORTED_PROTOCOL) result = CURLE_OK; } @@ -958,14 +972,16 @@ 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); + stmv.tv_sec = 0; + stmv.tv_usec = 0; if(timeout_ms < 0) timeout_ms = 0; - stmv.tv_sec = timeout_ms / 1000; - stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000; - switch(QsoWaitForIOCompletion(BACKEND->iocport, &cstat, &stmv)) { + switch(QsoWaitForIOCompletion(BACKEND->iocport, &cstat, + curlx_mstotv(&stmv, timeout_ms))) { case 1: /* Operation complete. */ break; case -1: /* An error occurred: handshake still in progress. */ @@ -1014,6 +1030,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, @@ -1070,15 +1087,16 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data, /* Check pinned public key. */ ptr = SSL_PINNED_PUB_KEY(); if(!result && ptr) { - curl_X509certificate x509; - curl_asn1Element *p; + struct Curl_X509certificate x509; + struct Curl_asn1Element *p; + memset(&x509, 0, sizeof(x509)); if(Curl_parseX509(&x509, cert, certend)) return CURLE_SSL_PINNEDPUBKEYNOTMATCH; p = &x509.subjectPublicKeyInfo; result = Curl_pin_peer_pubkey(data, ptr, p->header, p->end - p->header); if(result) { - failf(data, "SSL: public key does not match pinned public key!"); + failf(data, "SSL: public key does not match pinned public key"); return result; } } @@ -1205,6 +1223,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; @@ -1268,6 +1288,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 */ @@ -1287,6 +1308,7 @@ static void *gskit_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) { (void)info; + DEBUGASSERT(BACKEND); return BACKEND->handle; } @@ -1308,6 +1330,7 @@ const struct Curl_ssl Curl_ssl_gskit = { Curl_none_cert_status_request, /* cert_status_request */ gskit_connect, /* connect */ gskit_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ gskit_get_internals, /* get_internals */ gskit_close, /* close_one */ Curl_none_close_all, /* close_all */ |