1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 08:08:50 -05:00

gskit.c: use 'CURLcode result'

This commit is contained in:
Patrick Monnerat 2014-10-24 15:16:05 +02:00
parent ec783dc142
commit 897ef500e5

View File

@ -164,8 +164,6 @@ static bool is_separator(char c)
static CURLcode gskit_status(struct SessionHandle *data, int rc,
const char *procname, CURLcode defcode)
{
CURLcode cc;
/* Process GSKit status and map it to a CURLcode. */
switch (rc) {
case GSK_OK:
@ -298,7 +296,7 @@ static CURLcode set_ciphers(struct SessionHandle *data,
int i;
int l;
bool unsupported;
CURLcode cc;
CURLcode result;
struct {
char *buf;
char *ptr;
@ -331,7 +329,7 @@ static CURLcode set_ciphers(struct SessionHandle *data,
/* Process each cipher in input string. */
unsupported = FALSE;
cc = CURLE_OK;
result = CURLE_OK;
for(;;) {
for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
cipherlist++;
@ -344,7 +342,7 @@ static CURLcode set_ciphers(struct SessionHandle *data,
break;
if(!ctp->name) {
failf(data, "Unknown cipher %.*s", l, clp);
cc = CURLE_SSL_CIPHER;
result = CURLE_SSL_CIPHER;
}
else {
unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
@ -372,53 +370,53 @@ static CURLcode set_ciphers(struct SessionHandle *data,
/* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
cc = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
cc = CURLE_OK;
result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
result = CURLE_OK;
if(unsupported) {
failf(data, "TLSv1.1-only ciphers are not yet supported");
cc = CURLE_SSL_CIPHER;
result = CURLE_SSL_CIPHER;
}
}
}
if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
cc = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
cc = CURLE_OK;
if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
result = CURLE_OK;
if(unsupported) {
failf(data, "TLSv1.2-only ciphers are not yet supported");
cc = CURLE_SSL_CIPHER;
result = CURLE_SSL_CIPHER;
}
}
}
/* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to
the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */
if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
cc = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
cc = CURLE_OK;
if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
result = CURLE_OK;
strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr,
ciphers[CURL_GSKPROTO_TLSV10].ptr);
}
}
/* Set-up other ciphers. */
if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
result = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
result = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
/* Clean-up. */
for(i = 0; i < CURL_GSKPROTO_LAST; i++)
free(ciphers[i].buf);
return cc;
return result;
}
@ -442,7 +440,7 @@ static CURLcode init_environment(struct SessionHandle *data,
const char *password)
{
int rc;
CURLcode c;
CURLcode result;
gsk_handle h;
/* Creates the GSKit environment. */
@ -458,29 +456,29 @@ static CURLcode init_environment(struct SessionHandle *data,
return CURLE_SSL_CONNECT_ERROR;
}
c = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
if(c == CURLE_OK && appid)
c = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
if(c == CURLE_OK && file)
c = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
if(c == CURLE_OK && label)
c = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
if(c == CURLE_OK && password)
c = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
result = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
if(!result && appid)
result = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
if(!result && file)
result = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
if(!result && label)
result = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
if(!result && password)
result = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
if(c == CURLE_OK) {
if(!result) {
/* Locate CAs, Client certificate and key according to our settings.
Note: this call may be blocking for some tenths of seconds. */
c = gskit_status(data, gsk_environment_init(h),
"gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
if(c == CURLE_OK) {
result = gskit_status(data, gsk_environment_init(h),
"gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
if(!result) {
*envir = h;
return c;
return result;
}
}
/* Error: rollback. */
gsk_environment_close(&h);
return c;
return result;
}
@ -558,7 +556,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
struct SessionHandle *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
gsk_handle envir;
CURLcode cc;
CURLcode result;
int rc;
char *keyringfile;
char *keyringpwd;
@ -600,18 +598,18 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
if(!envir) {
/* Use keyring mode. */
cc = init_environment(data, &envir, (const char *) NULL,
keyringfile, keyringlabel, keyringpwd);
if(cc != CURLE_OK)
return cc;
result = init_environment(data, &envir, (const char *) NULL,
keyringfile, keyringlabel, keyringpwd);
if(result)
return result;
}
/* Create secure session. */
cc = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
"gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
result = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
"gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
gsk_environment_close(&envir);
if(cc != CURLE_OK)
return cc;
if(result)
return result;
/* Determine which SSL/TLS version should be enabled. */
protoflags = CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
@ -643,81 +641,84 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
if(sni) {
cc = set_buffer(data, connssl->handle,
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
if(cc == CURLE_UNSUPPORTED_PROTOCOL)
cc = CURLE_OK;
result = set_buffer(data, connssl->handle,
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
if(result == CURLE_UNSUPPORTED_PROTOCOL)
result = CURLE_OK;
}
/* Set session parameters. */
if(cc == CURLE_OK) {
if(!result) {
/* Compute the handshake timeout. Since GSKit granularity is 1 second,
we round up the required value. */
timeout = Curl_timeleft(data, NULL, TRUE);
if(timeout < 0)
cc = CURLE_OPERATION_TIMEDOUT;
result = CURLE_OPERATION_TIMEDOUT;
else
cc = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
(timeout + 999) / 1000);
result = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
(timeout + 999) / 1000);
}
if(cc == CURLE_OK)
cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
if(cc == CURLE_OK)
cc = set_ciphers(data, connssl->handle, &protoflags);
if(!result)
result = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
if(!result)
result = set_ciphers(data, connssl->handle, &protoflags);
if(!protoflags) {
failf(data, "No SSL protocol/cipher combination enabled");
cc = CURLE_SSL_CIPHER;
result = CURLE_SSL_CIPHER;
}
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
(protoflags & CURL_GSKPROTO_SSLV2_MASK)?
GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
(protoflags & CURL_GSKPROTO_SSLV3_MASK)?
GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
(protoflags & CURL_GSKPROTO_TLSV10_MASK)?
GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
if(cc == CURLE_OK) {
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
(protoflags & CURL_GSKPROTO_TLSV11_MASK)?
GSK_TRUE: GSK_FALSE, TRUE);
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
cc = CURLE_OK;
if(!result)
result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
(protoflags & CURL_GSKPROTO_SSLV2_MASK)?
GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
if(!result)
result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
(protoflags & CURL_GSKPROTO_SSLV3_MASK)?
GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
if(!result)
result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
(protoflags & CURL_GSKPROTO_TLSV10_MASK)?
GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
if(!result) {
result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
(protoflags & CURL_GSKPROTO_TLSV11_MASK)?
GSK_TRUE: GSK_FALSE, TRUE);
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
result = CURLE_OK;
if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
failf(data, "TLS 1.1 not yet supported");
cc = CURLE_SSL_CIPHER;
result = CURLE_SSL_CIPHER;
}
}
}
if(cc == CURLE_OK) {
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
(protoflags & CURL_GSKPROTO_TLSV12_MASK)?
GSK_TRUE: GSK_FALSE, TRUE);
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
cc = CURLE_OK;
if(!result) {
result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
(protoflags & CURL_GSKPROTO_TLSV12_MASK)?
GSK_TRUE: GSK_FALSE, TRUE);
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
result = CURLE_OK;
if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
failf(data, "TLS 1.2 not yet supported");
cc = CURLE_SSL_CIPHER;
result = CURLE_SSL_CIPHER;
}
}
}
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
GSK_SERVER_AUTH_PASSTHRU, FALSE);
if(!result)
result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
GSK_SERVER_AUTH_PASSTHRU, FALSE);
if(cc == CURLE_OK) {
if(!result) {
/* Start handshake. Try asynchronous first. */
memset(&commarea, 0, sizeof commarea);
connssl->iocport = QsoCreateIOCompletionPort();
if(connssl->iocport != -1) {
cc = gskit_status(data, gsk_secure_soc_startInit(connssl->handle,
connssl->iocport, &commarea),
"gsk_secure_soc_startInit()", CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK) {
result = gskit_status(data,
gsk_secure_soc_startInit(connssl->handle,
connssl->iocport,
&commarea),
"gsk_secure_soc_startInit()",
CURLE_SSL_CONNECT_ERROR);
if(!result) {
connssl->connecting_state = ssl_connect_2;
return CURLE_OK;
}
@ -725,12 +726,13 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
close_async_handshake(connssl);
}
else if(errno != ENOBUFS)
cc = gskit_status(data, GSK_ERROR_IO, "QsoCreateIOCompletionPort()", 0);
result = gskit_status(data, GSK_ERROR_IO,
"QsoCreateIOCompletionPort()", 0);
else {
/* No more completion port available. Use synchronous IO. */
cc = gskit_status(data, gsk_secure_soc_init(connssl->handle),
"gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK) {
result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
"gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
if(!result) {
connssl->connecting_state = ssl_connect_3;
return CURLE_OK;
}
@ -739,7 +741,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
/* Error: rollback. */
close_one(connssl, data);
return cc;
return result;
}
@ -751,7 +753,7 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
Qso_OverlappedIO_t cstat;
long timeout_ms;
struct timeval stmv;
CURLcode cc;
CURLcode result;
/* Poll or wait for end of SSL asynchronous handshake. */
@ -786,12 +788,12 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
}
break;
}
cc = gskit_status(data, cstat.returnValue, "SSL handshake",
CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK)
result = gskit_status(data, cstat.returnValue, "SSL handshake",
CURLE_SSL_CONNECT_ERROR);
if(!result)
connssl->connecting_state = ssl_connect_3;
close_async_handshake(connssl);
return cc;
return result;
}
@ -806,7 +808,7 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
const char *certend;
const char *ptr;
int i;
CURLcode cc;
CURLcode result;
/* SSL handshake done: gather certificate info and verify host. */
@ -839,9 +841,9 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
}
/* Verify host. */
cc = Curl_verifyhost(conn, cert, certend);
if(cc != CURLE_OK)
return cc;
result = Curl_verifyhost(conn, cert, certend);
if(result)
return result;
/* The only place GSKit can get the whole CA chain is a validation
callback where no user data pointer is available. Therefore it's not
@ -852,15 +854,15 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
if(Curl_ssl_init_certinfo(data, 1))
return CURLE_OUT_OF_MEMORY;
if(cert) {
cc = Curl_extract_certinfo(conn, 0, cert, certend);
if(cc != CURLE_OK)
return cc;
result = Curl_extract_certinfo(conn, 0, cert, certend);
if(result)
return result;
}
}
/* Check pinned public key. */
ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(cc == CURLE_OK && ptr) {
if(!result && ptr) {
curl_X509certificate x509;
curl_asn1Element *p;
@ -868,10 +870,10 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
Curl_parseX509(&x509, cert, certend);
p = &x509.subjectPublicKeyInfo;
cc = Curl_pin_peer_pubkey(ptr, p->header, p->end - p->header);
if(cc != CURLE_OK) {
result = Curl_pin_peer_pubkey(ptr, p->header, p->end - p->header);
if(result) {
failf(data, "SSL: public key does not match pinned public key!");
return cc;
return result;
}
}
@ -887,7 +889,7 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
long timeout_ms;
Qso_OverlappedIO_t cstat;
CURLcode cc = CURLE_OK;
CURLcode result = CURLE_OK;
*done = connssl->state == ssl_connection_complete;
if(*done)
@ -901,31 +903,31 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
cc = CURLE_OPERATION_TIMEDOUT;
result = CURLE_OPERATION_TIMEDOUT;
}
else
cc = gskit_connect_step1(conn, sockindex);
result = gskit_connect_step1(conn, sockindex);
}
/* Step 2: check if handshake is over. */
if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_2) {
if(!result && connssl->connecting_state == ssl_connect_2) {
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
cc = CURLE_OPERATION_TIMEDOUT;
result = CURLE_OPERATION_TIMEDOUT;
}
else
cc = gskit_connect_step2(conn, sockindex, nonblocking);
result = gskit_connect_step2(conn, sockindex, nonblocking);
}
/* Step 3: gather certificate info, verify host. */
if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_3)
cc = gskit_connect_step3(conn, sockindex);
if(!result && connssl->connecting_state == ssl_connect_3)
result = gskit_connect_step3(conn, sockindex);
if(cc != CURLE_OK)
if(result)
close_one(connssl, data);
else if(connssl->connecting_state == ssl_connect_done) {
connssl->state = ssl_connection_complete;
@ -935,7 +937,7 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
*done = TRUE;
}
return cc;
return result;
}
@ -943,24 +945,24 @@ CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
int sockindex,
bool *done)
{
CURLcode cc;
CURLcode result;
cc = gskit_connect_common(conn, sockindex, TRUE, done);
if(*done || cc != CURLE_OK)
result = gskit_connect_common(conn, sockindex, TRUE, done);
if(*done || result)
conn->ssl[sockindex].connecting_state = ssl_connect_1;
return cc;
return result;
}
CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
{
CURLcode retcode;
CURLcode result;
bool done;
conn->ssl[sockindex].connecting_state = ssl_connect_1;
retcode = gskit_connect_common(conn, sockindex, FALSE, &done);
if(retcode)
return retcode;
result = gskit_connect_common(conn, sockindex, FALSE, &done);
if(result)
return result;
DEBUGASSERT(done);