summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/vtls/gskit.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/vtls/gskit.c')
-rw-r--r--Utilities/cmcurl/lib/vtls/gskit.c79
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 */