Loading lib/vtls/gskit.c +143 −141 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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; Loading Loading @@ -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++; Loading @@ -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 | Loading Loading @@ -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, result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS, ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE); if(cc == CURLE_UNSUPPORTED_PROTOCOL) { cc = CURLE_OK; 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, if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) { result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS, ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE); if(cc == CURLE_UNSUPPORTED_PROTOCOL) { cc = CURLE_OK; 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, if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) { result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS, ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE); if(cc == CURLE_UNSUPPORTED_PROTOCOL) { cc = CURLE_OK; 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, if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK)) result = 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, 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; } Loading @@ -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. */ Loading @@ -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), result = gskit_status(data, gsk_environment_init(h), "gsk_environment_init()", CURLE_SSL_CERTPROBLEM); if(c == CURLE_OK) { if(!result) { *envir = h; return c; return result; } } /* Error: rollback. */ gsk_environment_close(&h); return c; return result; } Loading Loading @@ -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; Loading Loading @@ -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, result = init_environment(data, &envir, (const char *) NULL, keyringfile, keyringlabel, keyringpwd); if(cc != CURLE_OK) return cc; if(result) return result; } /* Create secure session. */ cc = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle), 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 | Loading Loading @@ -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, result = set_buffer(data, connssl->handle, GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE); if(cc == CURLE_UNSUPPORTED_PROTOCOL) cc = CURLE_OK; 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, 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, 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(cc == CURLE_OK) cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3, 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(cc == CURLE_OK) cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1, 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(cc == CURLE_OK) { cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11, if(!result) { result = 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 == 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, if(!result) { result = 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 == 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, 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; } Loading @@ -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), result = gskit_status(data, gsk_secure_soc_init(connssl->handle), "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR); if(cc == CURLE_OK) { if(!result) { connssl->connecting_state = ssl_connect_3; return CURLE_OK; } Loading @@ -739,7 +741,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex) /* Error: rollback. */ close_one(connssl, data); return cc; return result; } Loading @@ -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. */ Loading Loading @@ -786,12 +788,12 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex, } break; } cc = gskit_status(data, cstat.returnValue, "SSL handshake", result = gskit_status(data, cstat.returnValue, "SSL handshake", CURLE_SSL_CONNECT_ERROR); if(cc == CURLE_OK) if(!result) connssl->connecting_state = ssl_connect_3; close_async_handshake(connssl); return cc; return result; } Loading @@ -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. */ Loading Loading @@ -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 Loading @@ -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; Loading @@ -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; } } Loading @@ -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) Loading @@ -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; Loading @@ -935,7 +937,7 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex, *done = TRUE; } return cc; return result; } Loading @@ -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); Loading Loading
lib/vtls/gskit.c +143 −141 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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; Loading Loading @@ -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++; Loading @@ -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 | Loading Loading @@ -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, result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS, ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE); if(cc == CURLE_UNSUPPORTED_PROTOCOL) { cc = CURLE_OK; 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, if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) { result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS, ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE); if(cc == CURLE_UNSUPPORTED_PROTOCOL) { cc = CURLE_OK; 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, if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) { result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS, ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE); if(cc == CURLE_UNSUPPORTED_PROTOCOL) { cc = CURLE_OK; 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, if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK)) result = 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, 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; } Loading @@ -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. */ Loading @@ -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), result = gskit_status(data, gsk_environment_init(h), "gsk_environment_init()", CURLE_SSL_CERTPROBLEM); if(c == CURLE_OK) { if(!result) { *envir = h; return c; return result; } } /* Error: rollback. */ gsk_environment_close(&h); return c; return result; } Loading Loading @@ -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; Loading Loading @@ -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, result = init_environment(data, &envir, (const char *) NULL, keyringfile, keyringlabel, keyringpwd); if(cc != CURLE_OK) return cc; if(result) return result; } /* Create secure session. */ cc = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle), 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 | Loading Loading @@ -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, result = set_buffer(data, connssl->handle, GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE); if(cc == CURLE_UNSUPPORTED_PROTOCOL) cc = CURLE_OK; 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, 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, 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(cc == CURLE_OK) cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3, 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(cc == CURLE_OK) cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1, 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(cc == CURLE_OK) { cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11, if(!result) { result = 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 == 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, if(!result) { result = 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 == 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, 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; } Loading @@ -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), result = gskit_status(data, gsk_secure_soc_init(connssl->handle), "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR); if(cc == CURLE_OK) { if(!result) { connssl->connecting_state = ssl_connect_3; return CURLE_OK; } Loading @@ -739,7 +741,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex) /* Error: rollback. */ close_one(connssl, data); return cc; return result; } Loading @@ -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. */ Loading Loading @@ -786,12 +788,12 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex, } break; } cc = gskit_status(data, cstat.returnValue, "SSL handshake", result = gskit_status(data, cstat.returnValue, "SSL handshake", CURLE_SSL_CONNECT_ERROR); if(cc == CURLE_OK) if(!result) connssl->connecting_state = ssl_connect_3; close_async_handshake(connssl); return cc; return result; } Loading @@ -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. */ Loading Loading @@ -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 Loading @@ -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; Loading @@ -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; } } Loading @@ -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) Loading @@ -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; Loading @@ -935,7 +937,7 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex, *done = TRUE; } return cc; return result; } Loading @@ -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); Loading