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

1338 lines
39 KiB
C
Raw Normal View History

2013-07-15 13:00:36 -04:00
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
2017-03-26 11:02:22 -04:00
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
2013-07-15 13:00:36 -04:00
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
2013-07-15 13:00:36 -04:00
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_GSKIT
#include <gskssl.h>
#include <qsoasync.h>
/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
2013-07-15 13:00:36 -04:00
#endif
#ifndef GSK_TLSV10_CIPHER_SPECS
#define GSK_TLSV10_CIPHER_SPECS 236
#endif
#ifndef GSK_TLSV11_CIPHER_SPECS
#define GSK_TLSV11_CIPHER_SPECS 237
#endif
#ifndef GSK_TLSV12_CIPHER_SPECS
#define GSK_TLSV12_CIPHER_SPECS 238
#endif
#ifndef GSK_PROTOCOL_TLSV11
#define GSK_PROTOCOL_TLSV11 437
#endif
#ifndef GSK_PROTOCOL_TLSV12
#define GSK_PROTOCOL_TLSV12 438
#endif
#ifndef GSK_FALSE
#define GSK_FALSE 0
#endif
#ifndef GSK_TRUE
#define GSK_TRUE 1
#endif
2013-07-15 13:00:36 -04:00
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"
#include "gskit.h"
2013-12-25 05:20:39 -05:00
#include "vtls.h"
2013-07-15 13:00:36 -04:00
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "strcase.h"
2013-07-15 13:00:36 -04:00
#include "x509asn1.h"
#include "curl_printf.h"
2013-07-15 13:00:36 -04:00
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
/* Directions. */
#define SOS_READ 0x01
#define SOS_WRITE 0x02
/* SSL version flags. */
#define CURL_GSKPROTO_SSLV2 0
#define CURL_GSKPROTO_SSLV2_MASK (1 << CURL_GSKPROTO_SSLV2)
#define CURL_GSKPROTO_SSLV3 1
#define CURL_GSKPROTO_SSLV3_MASK (1 << CURL_GSKPROTO_SSLV3)
#define CURL_GSKPROTO_TLSV10 2
#define CURL_GSKPROTO_TLSV10_MASK (1 << CURL_GSKPROTO_TLSV10)
#define CURL_GSKPROTO_TLSV11 3
#define CURL_GSKPROTO_TLSV11_MASK (1 << CURL_GSKPROTO_TLSV11)
#define CURL_GSKPROTO_TLSV12 4
#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
#define CURL_GSKPROTO_LAST 5
2013-07-15 13:00:36 -04:00
/* Supported ciphers. */
typedef struct {
const char *name; /* Cipher name. */
const char *gsktoken; /* Corresponding token for GSKit String. */
unsigned int versions; /* SSL version flags. */
2013-07-15 13:00:36 -04:00
} gskit_cipher;
static const gskit_cipher ciphertable[] = {
{ "null-md5", "01",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
{ "null-sha", "02",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
{ "exp-rc4-md5", "03",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
{ "rc4-md5", "04",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
{ "rc4-sha", "05",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
{ "exp-rc2-cbc-md5", "06",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
{ "exp-des-cbc-sha", "09",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK },
{ "des-cbc3-sha", "0A",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
{ "aes128-sha", "2F",
CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
CURL_GSKPROTO_TLSV12_MASK },
{ "aes256-sha", "35",
CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
CURL_GSKPROTO_TLSV12_MASK },
{ "null-sha256", "3B", CURL_GSKPROTO_TLSV12_MASK },
{ "aes128-sha256", "3C", CURL_GSKPROTO_TLSV12_MASK },
{ "aes256-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK },
{ "aes128-gcm-sha256",
"9C", CURL_GSKPROTO_TLSV12_MASK },
{ "aes256-gcm-sha384",
"9D", CURL_GSKPROTO_TLSV12_MASK },
{ "rc4-md5", "1", CURL_GSKPROTO_SSLV2_MASK },
{ "exp-rc4-md5", "2", CURL_GSKPROTO_SSLV2_MASK },
{ "rc2-md5", "3", CURL_GSKPROTO_SSLV2_MASK },
{ "exp-rc2-md5", "4", CURL_GSKPROTO_SSLV2_MASK },
{ "des-cbc-md5", "6", CURL_GSKPROTO_SSLV2_MASK },
{ "des-cbc3-md5", "7", CURL_GSKPROTO_SSLV2_MASK },
2013-07-15 13:00:36 -04:00
{ (const char *) NULL, (const char *) NULL, 0 }
};
static bool is_separator(char c)
{
/* Return whether character is a cipher list separator. */
switch(c) {
2013-07-15 13:00:36 -04:00
case ' ':
case '\t':
case ':':
case ',':
case ';':
return true;
}
return false;
}
static CURLcode gskit_status(struct Curl_easy *data, int rc,
const char *procname, CURLcode defcode)
2013-07-15 13:00:36 -04:00
{
/* Process GSKit status and map it to a CURLcode. */
switch(rc) {
2013-07-15 13:00:36 -04:00
case GSK_OK:
case GSK_OS400_ASYNCHRONOUS_SOC_INIT:
return CURLE_OK;
case GSK_KEYRING_OPEN_ERROR:
case GSK_OS400_ERROR_NO_ACCESS:
return CURLE_SSL_CACERT_BADFILE;
case GSK_INSUFFICIENT_STORAGE:
return CURLE_OUT_OF_MEMORY;
case GSK_ERROR_BAD_V2_CIPHER:
case GSK_ERROR_BAD_V3_CIPHER:
case GSK_ERROR_NO_CIPHERS:
return CURLE_SSL_CIPHER;
case GSK_OS400_ERROR_NOT_TRUSTED_ROOT:
case GSK_ERROR_CERT_VALIDATION:
return CURLE_PEER_FAILED_VERIFICATION;
case GSK_OS400_ERROR_TIMED_OUT:
return CURLE_OPERATION_TIMEDOUT;
case GSK_WOULD_BLOCK:
return CURLE_AGAIN;
case GSK_OS400_ERROR_NOT_REGISTERED:
break;
case GSK_ERROR_IO:
switch(errno) {
2013-07-15 13:00:36 -04:00
case ENOMEM:
return CURLE_OUT_OF_MEMORY;
default:
failf(data, "%s I/O error: %s", procname, strerror(errno));
break;
}
break;
default:
failf(data, "%s: %s", procname, gsk_strerror(rc));
break;
}
2013-07-15 13:00:36 -04:00
return defcode;
}
static CURLcode set_enum(struct Curl_easy *data, gsk_handle h,
GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok)
2013-07-15 13:00:36 -04:00
{
int rc = gsk_attribute_set_enum(h, id, value);
switch(rc) {
2013-07-15 13:00:36 -04:00
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
break;
case GSK_ATTRIBUTE_INVALID_ID:
if(unsupported_ok)
return CURLE_UNSUPPORTED_PROTOCOL;
2013-07-15 13:00:36 -04:00
default:
failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_buffer(struct Curl_easy *data, gsk_handle h,
GSK_BUF_ID id, const char *buffer, bool unsupported_ok)
2013-07-15 13:00:36 -04:00
{
int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
switch(rc) {
2013-07-15 13:00:36 -04:00
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
break;
case GSK_ATTRIBUTE_INVALID_ID:
if(unsupported_ok)
return CURLE_UNSUPPORTED_PROTOCOL;
2013-07-15 13:00:36 -04:00
default:
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_numeric(struct Curl_easy *data,
2013-07-15 13:00:36 -04:00
gsk_handle h, GSK_NUM_ID id, int value)
{
int rc = gsk_attribute_set_numeric_value(h, id, value);
switch(rc) {
2013-07-15 13:00:36 -04:00
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_numeric_value() I/O error: %s",
strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_callback(struct Curl_easy *data,
gsk_handle h, GSK_CALLBACK_ID id, void *info)
2013-07-15 13:00:36 -04:00
{
int rc = gsk_attribute_set_callback(h, id, info);
switch(rc) {
2013-07-15 13:00:36 -04:00
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_callback() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
static CURLcode set_ciphers(struct connectdata *conn,
gsk_handle h, unsigned int *protoflags)
2013-07-15 13:00:36 -04:00
{
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
struct Curl_easy *data = conn->data;
const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
const char *clp;
const gskit_cipher *ctp;
2013-07-15 13:00:36 -04:00
int i;
int l;
bool unsupported;
2014-10-24 09:16:05 -04:00
CURLcode result;
struct {
char *buf;
char *ptr;
} ciphers[CURL_GSKPROTO_LAST];
2013-07-15 13:00:36 -04:00
/* Compile cipher list into GSKit-compatible cipher lists. */
if(!cipherlist)
return CURLE_OK;
while(is_separator(*cipherlist)) /* Skip initial separators. */
cipherlist++;
if(!*cipherlist)
return CURLE_OK;
/* We allocate GSKit buffers of the same size as the input string: since
GSKit tokens are always shorter than their cipher names, allocated buffers
2017-03-26 11:02:22 -04:00
will always be large enough to accommodate the result. */
l = strlen(cipherlist) + 1;
memset((char *) ciphers, 0, sizeof ciphers);
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
ciphers[i].buf = malloc(l);
if(!ciphers[i].buf) {
while(i--)
free(ciphers[i].buf);
return CURLE_OUT_OF_MEMORY;
}
ciphers[i].ptr = ciphers[i].buf;
*ciphers[i].ptr = '\0';
2013-07-15 13:00:36 -04:00
}
/* Process each cipher in input string. */
unsupported = FALSE;
2014-10-24 09:16:05 -04:00
result = CURLE_OK;
2013-07-15 13:00:36 -04:00
for(;;) {
for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
cipherlist++;
l = cipherlist - clp;
if(!l)
2013-07-15 13:00:36 -04:00
break;
/* Search the cipher in our table. */
for(ctp = ciphertable; ctp->name; ctp++)
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
if(strncasecompare(ctp->name, clp, l) && !ctp->name[l])
2013-07-15 13:00:36 -04:00
break;
if(!ctp->name) {
failf(data, "Unknown cipher %.*s", l, clp);
2014-10-24 09:16:05 -04:00
result = CURLE_SSL_CIPHER;
}
2013-07-15 13:00:36 -04:00
else {
unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK));
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
if(ctp->versions & (1 << i)) {
strcpy(ciphers[i].ptr, ctp->gsktoken);
ciphers[i].ptr += strlen(ctp->gsktoken);
}
2013-07-15 13:00:36 -04:00
}
}
/* Advance to next cipher name or end of string. */
while(is_separator(*cipherlist))
cipherlist++;
}
/* Disable protocols with empty cipher lists. */
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) {
*protoflags &= ~(1 << i);
ciphers[i].buf[0] = '\0';
}
}
/* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
2014-10-24 09:16:05 -04:00
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");
2014-10-24 09:16:05 -04:00
result = CURLE_SSL_CIPHER;
}
}
}
2014-10-24 09:16:05 -04:00
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");
2014-10-24 09:16:05 -04:00
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. */
2014-10-24 09:16:05 -04:00
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. */
2014-10-24 09:16:05 -04:00
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);
2014-10-24 09:16:05 -04:00
return result;
2013-07-15 13:00:36 -04:00
}
int Curl_gskit_init(void)
{
/* No initialisation needed. */
return 1;
}
void Curl_gskit_cleanup(void)
{
/* Nothing to do. */
}
static CURLcode init_environment(struct Curl_easy *data,
gsk_handle *envir, const char *appid,
const char *file, const char *label,
const char *password)
2013-07-15 13:00:36 -04:00
{
int rc;
2014-10-24 09:16:05 -04:00
CURLcode result;
2013-07-15 13:00:36 -04:00
gsk_handle h;
/* Creates the GSKit environment. */
rc = gsk_environment_open(&h);
switch(rc) {
2013-07-15 13:00:36 -04:00
case GSK_OK:
break;
case GSK_INSUFFICIENT_STORAGE:
return CURLE_OUT_OF_MEMORY;
default:
failf(data, "gsk_environment_open(): %s", gsk_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
}
2014-10-24 09:16:05 -04:00
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);
2013-07-15 13:00:36 -04:00
2014-10-24 09:16:05 -04:00
if(!result) {
2013-07-15 13:00:36 -04:00
/* Locate CAs, Client certificate and key according to our settings.
Note: this call may be blocking for some tenths of seconds. */
2014-10-24 09:16:05 -04:00
result = gskit_status(data, gsk_environment_init(h),
"gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
if(!result) {
2013-07-15 13:00:36 -04:00
*envir = h;
2014-10-24 09:16:05 -04:00
return result;
2013-07-15 13:00:36 -04:00
}
}
/* Error: rollback. */
gsk_environment_close(&h);
2014-10-24 09:16:05 -04:00
return result;
2013-07-15 13:00:36 -04:00
}
static void cancel_async_handshake(struct connectdata *conn, int sockindex)
2013-07-15 13:00:36 -04:00
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2013-07-15 13:00:36 -04:00
Qso_OverlappedIO_t cstat;
if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
QsoWaitForIOCompletion(connssl->iocport, &cstat, (struct timeval *) NULL);
}
static void close_async_handshake(struct ssl_connect_data *connssl)
2013-07-15 13:00:36 -04:00
{
QsoDestroyIOCompletionPort(connssl->iocport);
connssl->iocport = -1;
}
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
/* SSL over SSL
* Problems:
* 1) GSKit can only perform SSL on an AF_INET or AF_INET6 stream socket. To
* pipe an SSL stream into another, it is therefore needed to have a pair
* of such communicating sockets and handle the pipelining explicitly.
* 2) OS/400 socketpair() is only implemented for domain AF_UNIX, thus cannot
* be used to produce the pipeline.
* The solution is to simulate socketpair() for AF_INET with low-level API
* listen(), bind() and connect().
*/
static int
inetsocketpair(int sv[2])
{
int lfd; /* Listening socket. */
int sfd; /* Server socket. */
int cfd; /* Client socket. */
int len;
struct sockaddr_in addr1;
struct sockaddr_in addr2;
/* Create listening socket on a local dynamic port. */
lfd = socket(AF_INET, SOCK_STREAM, 0);
if(lfd < 0)
return -1;
memset((char *) &addr1, 0, sizeof addr1);
addr1.sin_family = AF_INET;
addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr1.sin_port = 0;
if(bind(lfd, (struct sockaddr *) &addr1, sizeof addr1) ||
listen(lfd, 2) < 0) {
close(lfd);
return -1;
}
/* Get the allocated port. */
len = sizeof addr1;
if(getsockname(lfd, (struct sockaddr *) &addr1, &len) < 0) {
close(lfd);
return -1;
}
/* Create the client socket. */
cfd = socket(AF_INET, SOCK_STREAM, 0);
if(cfd < 0) {
close(lfd);
return -1;
}
/* Request unblocking connection to the listening socket. */
curlx_nonblock(cfd, TRUE);
if(connect(cfd, (struct sockaddr *) &addr1, sizeof addr1) < 0 &&
errno != EINPROGRESS) {
close(lfd);
close(cfd);
return -1;
}
/* Get the client dynamic port for intrusion check below. */
len = sizeof addr2;
if(getsockname(cfd, (struct sockaddr *) &addr2, &len) < 0) {
close(lfd);
close(cfd);
return -1;
}
/* Accept the incoming connection and get the server socket. */
curlx_nonblock(lfd, TRUE);
for(;;) {
len = sizeof addr1;
sfd = accept(lfd, (struct sockaddr *) &addr1, &len);
if(sfd < 0) {
close(lfd);
close(cfd);
return -1;
}
/* Check for possible intrusion from an external process. */
if(addr1.sin_addr.s_addr == addr2.sin_addr.s_addr &&
addr1.sin_port == addr2.sin_port)
break;
/* Intrusion: reject incoming connection. */
close(sfd);
}
/* Done, return sockets and succeed. */
close(lfd);
curlx_nonblock(cfd, FALSE);
sv[0] = cfd;
sv[1] = sfd;
return 0;
}
static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
int directions)
{
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;
int n;
int m;
int i;
int ret = 0;
struct timeval tv = {0, 0};
char buf[CURL_MAX_WRITE_SIZE];
if(!connssl->use || !connproxyssl->use)
return 0; /* No SSL over SSL: OK. */
FD_ZERO(&fds_read);
FD_ZERO(&fds_write);
n = -1;
if(directions & SOS_READ) {
FD_SET(connssl->remotefd, &fds_write);
n = connssl->remotefd;
}
if(directions & SOS_WRITE) {
FD_SET(connssl->remotefd, &fds_read);
n = connssl->remotefd;
FD_SET(conn->sock[sockindex], &fds_write);
if(n < conn->sock[sockindex])
n = conn->sock[sockindex];
}
i = select(n + 1, &fds_read, &fds_write, NULL, &tv);
if(i < 0)
return -1; /* Select error. */
if(FD_ISSET(connssl->remotefd, &fds_write)) {
/* Try getting data from HTTPS proxy and pipe it upstream. */
n = 0;
i = gsk_secure_soc_read(connproxyssl->handle, buf, sizeof buf, &n);
switch(i) {
case GSK_OK:
if(n) {
i = write(connssl->remotefd, buf, n);
if(i < 0)
return -1;
ret = 1;
}
break;
case GSK_OS400_ERROR_TIMED_OUT:
case GSK_WOULD_BLOCK:
break;
default:
return -1;
}
}
if(FD_ISSET(connssl->remotefd, &fds_read) &&
FD_ISSET(conn->sock[sockindex], &fds_write)) {
/* Pipe data to HTTPS proxy. */
n = read(connssl->remotefd, buf, sizeof buf);
if(n < 0)
return -1;
if(n) {
i = gsk_secure_soc_write(connproxyssl->handle, buf, n, &m);
if(i != GSK_OK || n != m)
return -1;
ret = 1;
}
}
return ret; /* OK */
}
2013-07-15 13:00:36 -04:00
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
static void close_one(struct ssl_connect_data *connssl,
struct connectdata *conn, int sockindex)
2013-07-15 13:00:36 -04:00
{
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
if(connssl->handle) {
gskit_status(conn->data, gsk_secure_soc_close(&connssl->handle),
2013-07-15 13:00:36 -04:00
"gsk_secure_soc_close()", 0);
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
/* Last chance to drain output. */
while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0)
;
connssl->handle = (gsk_handle) NULL;
if(connssl->localfd >= 0) {
close(connssl->localfd);
connssl->localfd = -1;
}
if(connssl->remotefd >= 0) {
close(connssl->remotefd);
connssl->remotefd = -1;
}
2013-07-15 13:00:36 -04:00
}
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
if(connssl->iocport >= 0)
close_async_handshake(connssl);
2013-07-15 13:00:36 -04:00
}
static ssize_t gskit_send(struct connectdata *conn, int sockindex,
const void *mem, size_t len, CURLcode *curlcode)
2013-07-15 13:00:36 -04:00
{
struct Curl_easy *data = conn->data;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
CURLcode cc = CURLE_SEND_ERROR;
2013-07-15 13:00:36 -04:00
int written;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) >= 0) {
cc = gskit_status(data,
gsk_secure_soc_write(conn->ssl[sockindex].handle,
(char *) mem, (int) len, &written),
"gsk_secure_soc_write()", CURLE_SEND_ERROR);
if(cc == CURLE_OK)
if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) < 0)
cc = CURLE_SEND_ERROR;
}
2013-07-15 13:00:36 -04:00
if(cc != CURLE_OK) {
*curlcode = cc;
written = -1;
}
return (ssize_t) written; /* number of bytes */
}
static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
size_t buffersize, CURLcode *curlcode)
2013-07-15 13:00:36 -04:00
{
struct Curl_easy *data = conn->data;
2013-07-15 13:00:36 -04:00
int buffsize;
int nread;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
CURLcode cc = CURLE_RECV_ERROR;
2013-07-15 13:00:36 -04:00
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) {
buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle,
buf, buffsize, &nread),
"gsk_secure_soc_read()", CURLE_RECV_ERROR);
}
switch(cc) {
case CURLE_OK:
break;
case CURLE_OPERATION_TIMEDOUT:
cc = CURLE_AGAIN;
default:
2013-07-15 13:00:36 -04:00
*curlcode = cc;
nread = -1;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
break;
2013-07-15 13:00:36 -04:00
}
return (ssize_t) nread;
}
static CURLcode
set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
long ssl_version = SSL_CONN_CONFIG(version);
long ssl_version_max = SSL_CONN_CONFIG(version_max);
long i = ssl_version;
switch(ssl_version_max) {
case CURL_SSLVERSION_MAX_NONE:
ssl_version_max = ssl_version;
break;
case CURL_SSLVERSION_MAX_DEFAULT:
ssl_version_max = CURL_SSLVERSION_TLSv1_2;
break;
}
for(; i <= (ssl_version_max >> 16); ++i) {
switch(i) {
case CURL_SSLVERSION_TLSv1_0:
*protoflags |= CURL_GSKPROTO_TLSV10_MASK;
break;
case CURL_SSLVERSION_TLSv1_1:
*protoflags |= CURL_GSKPROTO_TLSV11_MASK;
break;
case CURL_SSLVERSION_TLSv1_2:
*protoflags |= CURL_GSKPROTO_TLSV11_MASK;
break;
case CURL_SSLVERSION_TLSv1_3:
failf(data, "GSKit: TLS 1.3 is not yet supported");
return CURLE_SSL_CONNECT_ERROR;
}
}
return CURLE_OK;
}
2013-07-15 13:00:36 -04:00
static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
2013-07-15 13:00:36 -04:00
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2013-07-15 13:00:36 -04:00
gsk_handle envir;
2014-10-24 09:16:05 -04:00
CURLcode result;
2013-07-15 13:00:36 -04:00
int rc;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
const char * const keyringlabel = SSL_SET_OPTION(cert);
const long int ssl_version = SSL_CONN_CONFIG(version);
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
conn->host.name;
const char *sni;
unsigned int protoflags = 0;
2013-07-15 13:00:36 -04:00
long timeout;
Qso_OverlappedIO_t commarea;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
int sockpair[2];
static const int sobufsize = CURL_MAX_WRITE_SIZE;
2013-07-15 13:00:36 -04:00
/* Create SSL environment, start (preferably asynchronous) handshake. */
connssl->handle = (gsk_handle) NULL;
connssl->iocport = -1;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
connssl->localfd = -1;
connssl->remotefd = -1;
2013-07-15 13:00:36 -04:00
/* GSKit supports two ways of specifying an SSL context: either by
* application identifier (that should have been defined at the system
* level) or by keyring file, password and certificate label.
* Local certificate name (CURLOPT_SSLCERT) is used to hold either the
* application identifier of the certificate label.
* Key password (CURLOPT_KEYPASSWD) holds the keyring password.
* It is not possible to have different keyrings for the CAs and the
* local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
* the keyring file.
* If no key password is given and the keyring is the system keyring,
* application identifier mode is tried first, as recommended in IBM doc.
*/
envir = (gsk_handle) NULL;
if(keyringlabel && *keyringlabel && !keyringpwd &&
!strcmp(keyringfile, CURL_CA_BUNDLE)) {
/* Try application identifier mode. */
init_environment(data, &envir, keyringlabel, (const char *) NULL,
(const char *) NULL, (const char *) NULL);
}
if(!envir) {
/* Use keyring mode. */
2014-10-24 09:16:05 -04:00
result = init_environment(data, &envir, (const char *) NULL,
keyringfile, keyringlabel, keyringpwd);
if(result)
return result;
2013-07-15 13:00:36 -04:00
}
/* Create secure session. */
2014-10-24 09:16:05 -04:00
result = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
"gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
2013-07-15 13:00:36 -04:00
gsk_environment_close(&envir);
2014-10-24 09:16:05 -04:00
if(result)
return result;
2013-07-15 13:00:36 -04:00
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
/* Establish a pipelining socket pair for SSL over SSL. */
if(conn->proxy_ssl[sockindex].use) {
if(inetsocketpair(sockpair))
return CURLE_SSL_CONNECT_ERROR;
connssl->localfd = sockpair[0];
connssl->remotefd = sockpair[1];
setsockopt(connssl->localfd, SOL_SOCKET, SO_RCVBUF,
(void *) sobufsize, sizeof sobufsize);
setsockopt(connssl->remotefd, SOL_SOCKET, SO_RCVBUF,
(void *) sobufsize, sizeof sobufsize);
setsockopt(connssl->localfd, SOL_SOCKET, SO_SNDBUF,
(void *) sobufsize, sizeof sobufsize);
setsockopt(connssl->remotefd, SOL_SOCKET, SO_SNDBUF,
(void *) sobufsize, sizeof sobufsize);
curlx_nonblock(connssl->localfd, TRUE);
curlx_nonblock(connssl->remotefd, TRUE);
}
2013-07-15 13:00:36 -04:00
/* Determine which SSL/TLS version should be enabled. */
sni = hostname;
switch(ssl_version) {
2013-07-15 13:00:36 -04:00
case CURL_SSLVERSION_SSLv2:
protoflags = CURL_GSKPROTO_SSLV2_MASK;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
sni = NULL;
2013-07-15 13:00:36 -04:00
break;
case CURL_SSLVERSION_SSLv3:
2015-01-02 12:37:45 -05:00
protoflags = CURL_GSKPROTO_SSLV3_MASK;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
sni = NULL;
2013-07-15 13:00:36 -04:00
break;
case CURL_SSLVERSION_DEFAULT:
2013-07-15 13:00:36 -04:00
case CURL_SSLVERSION_TLSv1:
protoflags = CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
break;
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
result = set_ssl_version_min_max(&protoflags, conn);
if(result != CURLE_OK)
return result;
break;
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
return CURLE_SSL_CONNECT_ERROR;
2013-07-15 13:00:36 -04:00
}
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
if(sni) {
2014-10-24 09:16:05 -04:00
result = set_buffer(data, connssl->handle,
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
if(result == CURLE_UNSUPPORTED_PROTOCOL)
result = CURLE_OK;
2013-07-15 13:00:36 -04:00
}
/* Set session parameters. */
2014-10-24 09:16:05 -04:00
if(!result) {
2013-07-15 13:00:36 -04:00
/* 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)
2014-10-24 09:16:05 -04:00
result = CURLE_OPERATION_TIMEDOUT;
2013-07-15 13:00:36 -04:00
else
2014-10-24 09:16:05 -04:00
result = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
(timeout + 999) / 1000);
2013-07-15 13:00:36 -04:00
}
2014-10-24 09:16:05 -04:00
if(!result)
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
result = set_numeric(data, connssl->handle, GSK_OS400_READ_TIMEOUT, 1);
if(!result)
result = set_numeric(data, connssl->handle, GSK_FD, connssl->localfd >= 0?
connssl->localfd: conn->sock[sockindex]);
2014-10-24 09:16:05 -04:00
if(!result)
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
result = set_ciphers(conn, connssl->handle, &protoflags);
if(!protoflags) {
failf(data, "No SSL protocol/cipher combination enabled");
2014-10-24 09:16:05 -04:00
result = CURLE_SSL_CIPHER;
}
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");
2014-10-24 09:16:05 -04:00
result = CURLE_SSL_CIPHER;
}
}
}
2014-10-24 09:16:05 -04:00
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");
2014-10-24 09:16:05 -04:00
result = CURLE_SSL_CIPHER;
}
}
}
2014-10-24 09:16:05 -04:00
if(!result)
result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
verifypeer? GSK_SERVER_AUTH_FULL:
2014-10-24 09:16:05 -04:00
GSK_SERVER_AUTH_PASSTHRU, FALSE);
2013-07-15 13:00:36 -04:00
2014-10-24 09:16:05 -04:00
if(!result) {
2013-07-15 13:00:36 -04:00
/* Start handshake. Try asynchronous first. */
memset(&commarea, 0, sizeof commarea);
connssl->iocport = QsoCreateIOCompletionPort();
if(connssl->iocport != -1) {
2014-10-24 09:16:05 -04:00
result = gskit_status(data,
gsk_secure_soc_startInit(connssl->handle,
connssl->iocport,
&commarea),
"gsk_secure_soc_startInit()",
CURLE_SSL_CONNECT_ERROR);
if(!result) {
2013-07-15 13:00:36 -04:00
connssl->connecting_state = ssl_connect_2;
return CURLE_OK;
}
else
close_async_handshake(connssl);
}
else if(errno != ENOBUFS)
2014-10-24 09:16:05 -04:00
result = gskit_status(data, GSK_ERROR_IO,
"QsoCreateIOCompletionPort()", 0);
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
else if(conn->proxy_ssl[sockindex].use) {
/* Cannot pipeline while handshaking synchronously. */
result = CURLE_SSL_CONNECT_ERROR;
}
2013-07-15 13:00:36 -04:00
else {
/* No more completion port available. Use synchronous IO. */
2014-10-24 09:16:05 -04:00
result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
"gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
if(!result) {
2013-07-15 13:00:36 -04:00
connssl->connecting_state = ssl_connect_3;
return CURLE_OK;
}
}
}
/* Error: rollback. */
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
close_one(connssl, conn, sockindex);
2014-10-24 09:16:05 -04:00
return result;
2013-07-15 13:00:36 -04:00
}
static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
2013-07-15 13:00:36 -04:00
bool nonblocking)
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2013-07-15 13:00:36 -04:00
Qso_OverlappedIO_t cstat;
long timeout_ms;
struct timeval stmv;
2014-10-24 09:16:05 -04:00
CURLcode result;
2013-07-15 13:00:36 -04:00
/* Poll or wait for end of SSL asynchronous handshake. */
for(;;) {
timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
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(connssl->iocport, &cstat, &stmv)) {
2013-07-15 13:00:36 -04:00
case 1: /* Operation complete. */
break;
case -1: /* An error occurred: handshake still in progress. */
if(errno == EINTR) {
if(nonblocking)
return CURLE_OK;
continue; /* Retry. */
}
if(errno != ETIME) {
failf(data, "QsoWaitForIOCompletion() I/O error: %s", strerror(errno));
cancel_async_handshake(conn, sockindex);
close_async_handshake(connssl);
return CURLE_SSL_CONNECT_ERROR;
}
/* FALL INTO... */
case 0: /* Handshake in progress, timeout occurred. */
if(nonblocking)
return CURLE_OK;
cancel_async_handshake(conn, sockindex);
close_async_handshake(connssl);
return CURLE_OPERATION_TIMEDOUT;
}
break;
}
2014-10-24 09:16:05 -04:00
result = gskit_status(data, cstat.returnValue, "SSL handshake",
CURLE_SSL_CONNECT_ERROR);
if(!result)
2013-07-15 13:00:36 -04:00
connssl->connecting_state = ssl_connect_3;
close_async_handshake(connssl);
2014-10-24 09:16:05 -04:00
return result;
2013-07-15 13:00:36 -04:00
}
static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
2013-07-15 13:00:36 -04:00
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
const gsk_cert_data_elem *cdev;
2013-07-15 13:00:36 -04:00
int cdec;
const gsk_cert_data_elem *p;
const char *cert = (const char *) NULL;
const char *certend;
const char *ptr;
2013-07-15 13:00:36 -04:00
int i;
2014-10-24 09:16:05 -04:00
CURLcode result;
2013-07-15 13:00:36 -04:00
/* SSL handshake done: gather certificate info and verify host. */
if(gskit_status(data, gsk_attribute_get_cert_info(connssl->handle,
GSK_PARTNER_CERT_INFO,
&cdev, &cdec),
"gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
CURLE_OK) {
infof(data, "Server certificate:\n");
p = cdev;
for(i = 0; i++ < cdec; p++)
switch(p->cert_data_id) {
2013-07-15 13:00:36 -04:00
case CERT_BODY_DER:
cert = p->cert_data_p;
certend = cert + cdev->cert_data_l;
break;
case CERT_DN_PRINTABLE:
infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_ISSUER_DN_PRINTABLE:
infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_VALID_FROM:
infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_VALID_TO:
infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
}
}
/* Verify host. */
2014-10-24 09:16:05 -04:00
result = Curl_verifyhost(conn, cert, certend);
if(result)
return result;
2013-07-15 13:00:36 -04:00
/* 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
possible to copy this chain into our structures for CAINFO.
However the server certificate may be available, thus we can return
info about it. */
if(data->set.ssl.certinfo) {
result = Curl_ssl_init_certinfo(data, 1);
if(result)
return result;
2013-07-15 13:00:36 -04:00
if(cert) {
2014-10-24 09:16:05 -04:00
result = Curl_extract_certinfo(conn, 0, cert, certend);
if(result)
return result;
2013-07-15 13:00:36 -04:00
}
}
/* Check pinned public key. */
ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
2014-10-24 09:16:05 -04:00
if(!result && ptr) {
curl_X509certificate x509;
curl_asn1Element *p;
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);
2014-10-24 09:16:05 -04:00
if(result) {
failf(data, "SSL: public key does not match pinned public key!");
2014-10-24 09:16:05 -04:00
return result;
}
}
2013-07-15 13:00:36 -04:00
connssl->connecting_state = ssl_connect_done;
return CURLE_OK;
}
static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
bool nonblocking, bool *done)
2013-07-15 13:00:36 -04:00
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2013-07-15 13:00:36 -04:00
long timeout_ms;
Qso_OverlappedIO_t cstat;
2014-10-24 09:16:05 -04:00
CURLcode result = CURLE_OK;
2013-07-15 13:00:36 -04:00
*done = connssl->state == ssl_connection_complete;
if(*done)
return CURLE_OK;
/* Step 1: create session, start handshake. */
if(connssl->connecting_state == ssl_connect_1) {
/* 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");
2014-10-24 09:16:05 -04:00
result = CURLE_OPERATION_TIMEDOUT;
2013-07-15 13:00:36 -04:00
}
else
2014-10-24 09:16:05 -04:00
result = gskit_connect_step1(conn, sockindex);
2013-07-15 13:00:36 -04:00
}
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
/* Handle handshake pipelining. */
if(!result)
if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
result = CURLE_SSL_CONNECT_ERROR;
2013-07-15 13:00:36 -04:00
/* Step 2: check if handshake is over. */
2014-10-24 09:16:05 -04:00
if(!result && connssl->connecting_state == ssl_connect_2) {
2013-07-15 13:00:36 -04:00
/* 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");
2014-10-24 09:16:05 -04:00
result = CURLE_OPERATION_TIMEDOUT;
2013-07-15 13:00:36 -04:00
}
else
2014-10-24 09:16:05 -04:00
result = gskit_connect_step2(conn, sockindex, nonblocking);
2013-07-15 13:00:36 -04:00
}
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
/* Handle handshake pipelining. */
if(!result)
if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
result = CURLE_SSL_CONNECT_ERROR;
2013-07-15 13:00:36 -04:00
/* Step 3: gather certificate info, verify host. */
2014-10-24 09:16:05 -04:00
if(!result && connssl->connecting_state == ssl_connect_3)
result = gskit_connect_step3(conn, sockindex);
2013-07-15 13:00:36 -04:00
2014-10-24 09:16:05 -04:00
if(result)
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
close_one(connssl, conn, sockindex);
2013-07-15 13:00:36 -04:00
else if(connssl->connecting_state == ssl_connect_done) {
connssl->state = ssl_connection_complete;
connssl->connecting_state = ssl_connect_1;
conn->recv[sockindex] = gskit_recv;
conn->send[sockindex] = gskit_send;
*done = TRUE;
}
2014-10-24 09:16:05 -04:00
return result;
2013-07-15 13:00:36 -04:00
}
CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
2013-07-15 13:00:36 -04:00
int sockindex,
bool *done)
2013-07-15 13:00:36 -04:00
{
2014-10-24 09:16:05 -04:00
CURLcode result;
2013-07-15 13:00:36 -04:00
2014-10-24 09:16:05 -04:00
result = gskit_connect_common(conn, sockindex, TRUE, done);
if(*done || result)
2013-07-15 13:00:36 -04:00
conn->ssl[sockindex].connecting_state = ssl_connect_1;
2014-10-24 09:16:05 -04:00
return result;
2013-07-15 13:00:36 -04:00
}
CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
2013-07-15 13:00:36 -04:00
{
2014-10-24 09:16:05 -04:00
CURLcode result;
2013-07-15 13:00:36 -04:00
bool done;
conn->ssl[sockindex].connecting_state = ssl_connect_1;
2014-10-24 09:16:05 -04:00
result = gskit_connect_common(conn, sockindex, FALSE, &done);
if(result)
return result;
2013-07-15 13:00:36 -04:00
DEBUGASSERT(done);
return CURLE_OK;
}
void Curl_gskit_close(struct connectdata *conn, int sockindex)
2013-07-15 13:00:36 -04:00
{
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
close_one(&conn->ssl[sockindex], conn, sockindex);
close_one(&conn->proxy_ssl[sockindex], conn, sockindex);
2013-07-15 13:00:36 -04:00
}
int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
2013-07-15 13:00:36 -04:00
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct Curl_easy *data = conn->data;
2013-07-15 13:00:36 -04:00
ssize_t nread;
int what;
int rc;
char buf[120];
if(!connssl->handle)
return 0;
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
return 0;
proxy: Support HTTPS proxy and SOCKS+HTTP(s) * HTTPS proxies: An HTTPS proxy receives all transactions over an SSL/TLS connection. Once a secure connection with the proxy is established, the user agent uses the proxy as usual, including sending CONNECT requests to instruct the proxy to establish a [usually secure] TCP tunnel with an origin server. HTTPS proxies protect nearly all aspects of user-proxy communications as opposed to HTTP proxies that receive all requests (including CONNECT requests) in vulnerable clear text. With HTTPS proxies, it is possible to have two concurrent _nested_ SSL/TLS sessions: the "outer" one between the user agent and the proxy and the "inner" one between the user agent and the origin server (through the proxy). This change adds supports for such nested sessions as well. A secure connection with a proxy requires its own set of the usual SSL options (their actual descriptions differ and need polishing, see TODO): --proxy-cacert FILE CA certificate to verify peer against --proxy-capath DIR CA directory to verify peer against --proxy-cert CERT[:PASSWD] Client certificate file and password --proxy-cert-type TYPE Certificate file type (DER/PEM/ENG) --proxy-ciphers LIST SSL ciphers to use --proxy-crlfile FILE Get a CRL list in PEM format from the file --proxy-insecure Allow connections to proxies with bad certs --proxy-key KEY Private key file name --proxy-key-type TYPE Private key file type (DER/PEM/ENG) --proxy-pass PASS Pass phrase for the private key --proxy-ssl-allow-beast Allow security flaw to improve interop --proxy-sslv2 Use SSLv2 --proxy-sslv3 Use SSLv3 --proxy-tlsv1 Use TLSv1 --proxy-tlsuser USER TLS username --proxy-tlspassword STRING TLS password --proxy-tlsauthtype STRING TLS authentication type (default SRP) All --proxy-foo options are independent from their --foo counterparts, except --proxy-crlfile which defaults to --crlfile and --proxy-capath which defaults to --capath. Curl now also supports %{proxy_ssl_verify_result} --write-out variable, similar to the existing %{ssl_verify_result} variable. Supported backends: OpenSSL, GnuTLS, and NSS. * A SOCKS proxy + HTTP/HTTPS proxy combination: If both --socks* and --proxy options are given, Curl first connects to the SOCKS proxy and then connects (through SOCKS) to the HTTP or HTTPS proxy. TODO: Update documentation for the new APIs and --proxy-* options. Look for "Added in 7.XXX" marks.
2016-11-16 12:49:15 -05:00
close_one(connssl, conn, sockindex);
2013-07-15 13:00:36 -04:00
rc = 0;
what = SOCKET_READABLE(conn->sock[sockindex],
SSL_SHUTDOWN_TIMEOUT);
2013-07-15 13:00:36 -04:00
for(;;) {
if(what < 0) {
/* anything that gets here is fatally bad */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
rc = -1;
break;
}
if(!what) { /* timeout */
failf(data, "SSL shutdown timeout");
break;
}
/* Something to read, let's do it and hope that it is the close
notify alert from the server. No way to gsk_secure_soc_read() now, so
use read(). */
nread = read(conn->sock[sockindex], buf, sizeof(buf));
if(nread < 0) {
failf(data, "read: %s", strerror(errno));
rc = -1;
}
if(nread <= 0)
break;
what = SOCKET_READABLE(conn->sock[sockindex], 0);
2013-07-15 13:00:36 -04:00
}
return rc;
}
size_t Curl_gskit_version(char *buffer, size_t size)
2013-07-15 13:00:36 -04:00
{
strncpy(buffer, "GSKit", size);
return strlen(buffer);
}
int Curl_gskit_check_cxn(struct connectdata *cxn)
2013-07-15 13:00:36 -04:00
{
int err;
int errlen;
/* The only thing that can be tested here is at the socket level. */
if(!cxn->ssl[FIRSTSOCKET].handle)
return 0; /* connection has been closed */
err = 0;
errlen = sizeof err;
if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
(unsigned char *) &err, &errlen) ||
errlen != sizeof err || err)
return 0; /* connection has been closed */
return -1; /* connection status unknown */
}
#endif /* USE_GSKIT */