aboutsummaryrefslogtreecommitdiff
path: root/lib/vtls/openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vtls/openssl.c')
-rw-r--r--lib/vtls/openssl.c232
1 files changed, 134 insertions, 98 deletions
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index ae1a54f05..b8bc6c117 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -203,7 +203,7 @@ static CURLcode Curl_ossl_seed(struct Curl_easy *data)
#ifndef RANDOM_FILE
/* if RANDOM_FILE isn't defined, we only perform this if an option tells
us to! */
- if(data->set.ssl.random_file)
+ if(data->set.str[STRING_SSL_RANDOM_FILE])
#define RANDOM_FILE "" /* doesn't matter won't be used */
#endif
{
@@ -331,7 +331,8 @@ int cert_stuff(struct connectdata *conn,
char *cert_file,
const char *cert_type,
char *key_file,
- const char *key_type)
+ const char *key_type,
+ char *key_passwd)
{
struct Curl_easy *data = conn->data;
@@ -342,10 +343,9 @@ int cert_stuff(struct connectdata *conn,
X509 *x509;
int cert_done = 0;
- if(data->set.str[STRING_KEY_PASSWD]) {
+ if(key_passwd) {
/* set the password in the callback userdata */
- SSL_CTX_set_default_passwd_cb_userdata(ctx,
- data->set.str[STRING_KEY_PASSWD]);
+ SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd);
/* Set passwd callback: */
SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
}
@@ -456,7 +456,7 @@ int cert_stuff(struct connectdata *conn,
PKCS12_PBE_add();
- if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509,
+ if(!PKCS12_parse(p12, key_passwd, &pri, &x509,
&ca)) {
failf(data,
"could not parse PKCS12 file, check password, " OSSL_PACKAGE
@@ -568,7 +568,7 @@ int cert_stuff(struct connectdata *conn,
priv_key = (EVP_PKEY *)
ENGINE_load_private_key(data->state.engine, key_file,
ui_method,
- data->set.str[STRING_KEY_PASSWD]);
+ key_passwd);
UI_destroy_method(ui_method);
if(!priv_key) {
failf(data, "failed to load private key from crypto engine");
@@ -899,13 +899,8 @@ struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data)
}
-/*
- * This function is called when an SSL connection is closed.
- */
-void Curl_ossl_close(struct connectdata *conn, int sockindex)
+static void ossl_close(struct ssl_connect_data *connssl)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
if(connssl->handle) {
(void)SSL_shutdown(connssl->handle);
SSL_set_connect_state(connssl->handle);
@@ -920,6 +915,15 @@ void Curl_ossl_close(struct connectdata *conn, int sockindex)
}
/*
+ * This function is called when an SSL connection is closed.
+ */
+void Curl_ossl_close(struct connectdata *conn, int sockindex)
+{
+ ossl_close(&conn->ssl[sockindex]);
+ ossl_close(&conn->proxy_ssl[sockindex]);
+}
+
+/*
* This function is called to shut down the SSL layer but keep the
* socket open (CCC - Clear Command Channel)
*/
@@ -1090,16 +1094,20 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
CURLcode result = CURLE_OK;
bool dNSName = FALSE; /* if a dNSName field exists in the cert */
bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
+ const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+ conn->host.name;
+ const char * const dispname = SSL_IS_PROXY() ?
+ conn->http_proxy.host.dispname : conn->host.dispname;
#ifdef ENABLE_IPV6
if(conn->bits.ipv6_ip &&
- Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
+ Curl_inet_pton(AF_INET6, hostname, &addr)) {
target = GEN_IPADD;
addrlen = sizeof(struct in6_addr);
}
else
#endif
- if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
+ if(Curl_inet_pton(AF_INET, hostname, &addr)) {
target = GEN_IPADD;
addrlen = sizeof(struct in_addr);
}
@@ -1148,11 +1156,11 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
if((altlen == strlen(altptr)) &&
/* if this isn't true, there was an embedded zero in the name
string and we cannot match it. */
- Curl_cert_hostcheck(altptr, conn->host.name)) {
+ Curl_cert_hostcheck(altptr, hostname)) {
dnsmatched = TRUE;
infof(data,
" subjectAltName: host \"%s\" matched cert's \"%s\"\n",
- conn->host.dispname, altptr);
+ dispname, altptr);
}
break;
@@ -1163,7 +1171,7 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
ipmatched = TRUE;
infof(data,
" subjectAltName: host \"%s\" matched cert's IP address!\n",
- conn->host.dispname);
+ dispname);
}
break;
}
@@ -1179,9 +1187,9 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
/* an alternative name matched */
;
else if(dNSName || iPAddress) {
- infof(data, " subjectAltName does not match %s\n", conn->host.dispname);
+ infof(data, " subjectAltName does not match %s\n", dispname);
failf(data, "SSL: no alternative certificate subject name matches "
- "target host name '%s'", conn->host.dispname);
+ "target host name '%s'", dispname);
result = CURLE_PEER_FAILED_VERIFICATION;
}
else {
@@ -1255,9 +1263,9 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
"SSL: unable to obtain common name from peer certificate");
result = CURLE_PEER_FAILED_VERIFICATION;
}
- else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
+ else if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
failf(data, "SSL: certificate subject name '%s' does not match "
- "target host name '%s'", peer_CN, conn->host.dispname);
+ "target host name '%s'", peer_CN, dispname);
result = CURLE_PEER_FAILED_VERIFICATION;
}
else {
@@ -1703,6 +1711,20 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
struct in_addr addr;
#endif
#endif
+ long * const certverifyresult = SSL_IS_PROXY() ?
+ &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+ const long int ssl_version = SSL_CONN_CONFIG(version);
+#ifdef USE_TLS_SRP
+ const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
+#endif
+ char * const ssl_cert = SSL_SET_OPTION(cert);
+ const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
+ const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+ const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
+ const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+ const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
+ const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+ conn->host.name;
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
@@ -1711,11 +1733,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
if(result)
return result;
- data->set.ssl.certverifyresult = !X509_V_OK;
+ *certverifyresult = !X509_V_OK;
/* check to see if we've been told to use an explicit SSL/TLS version */
- switch(data->set.ssl.version) {
+ switch(ssl_version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
@@ -1737,7 +1759,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
return CURLE_NOT_BUILT_IN;
#else
#ifdef USE_TLS_SRP
- if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
+ if(ssl_authtype == CURL_TLSAUTH_SRP)
return CURLE_SSL_CONNECT_ERROR;
#endif
req_method = SSLv2_client_method();
@@ -1750,7 +1772,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
return CURLE_NOT_BUILT_IN;
#else
#ifdef USE_TLS_SRP
- if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
+ if(ssl_authtype == CURL_TLSAUTH_SRP)
return CURLE_SSL_CONNECT_ERROR;
#endif
req_method = SSLv3_client_method();
@@ -1838,14 +1860,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
/* unless the user explicitly ask to allow the protocol vulnerability we
use the work-around */
- if(!conn->data->set.ssl_enable_beast)
+ if(!SSL_SET_OPTION(enable_beast))
ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
- switch(data->set.ssl.version) {
+ switch(ssl_version) {
case CURL_SSLVERSION_SSLv3:
#ifdef USE_TLS_SRP
- if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
+ if(ssl_authtype == CURL_TLSAUTH_SRP) {
infof(data, "Set version TLSv1.x for SRP authorisation\n");
}
#endif
@@ -1979,19 +2001,16 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
}
#endif
- if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) {
- if(!cert_stuff(conn,
- connssl->ctx,
- data->set.str[STRING_CERT],
- data->set.str[STRING_CERT_TYPE],
- data->set.str[STRING_KEY],
- data->set.str[STRING_KEY_TYPE])) {
+ if(ssl_cert || ssl_cert_type) {
+ if(!cert_stuff(conn, connssl->ctx, ssl_cert, ssl_cert_type,
+ SSL_SET_OPTION(key), SSL_SET_OPTION(key_type),
+ SSL_SET_OPTION(key_passwd))) {
/* failf() is already done in cert_stuff() */
return CURLE_SSL_CERTPROBLEM;
}
}
- ciphers = data->set.str[STRING_SSL_CIPHER_LIST];
+ ciphers = SSL_CONN_CONFIG(cipher_list);
if(!ciphers)
ciphers = (char *)DEFAULT_CIPHER_SELECTION;
if(!SSL_CTX_set_cipher_list(connssl->ctx, ciphers)) {
@@ -2001,18 +2020,20 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
infof(data, "Cipher selection: %s\n", ciphers);
#ifdef USE_TLS_SRP
- if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
- infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
+ if(ssl_authtype == CURL_TLSAUTH_SRP) {
+ char * const ssl_username = SSL_SET_OPTION(username);
+
+ infof(data, "Using TLS-SRP username: %s\n", ssl_username);
- if(!SSL_CTX_set_srp_username(connssl->ctx, data->set.ssl.username)) {
+ if(!SSL_CTX_set_srp_username(connssl->ctx, ssl_username)) {
failf(data, "Unable to set SRP user name");
return CURLE_BAD_FUNCTION_ARGUMENT;
}
- if(!SSL_CTX_set_srp_password(connssl->ctx, data->set.ssl.password)) {
+ if(!SSL_CTX_set_srp_password(connssl->ctx, SSL_SET_OPTION(password))) {
failf(data, "failed setting SRP password");
return CURLE_BAD_FUNCTION_ARGUMENT;
}
- if(!data->set.str[STRING_SSL_CIPHER_LIST]) {
+ if(!SSL_CONN_CONFIG(cipher_list)) {
infof(data, "Setting cipher list SRP\n");
if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) {
@@ -2022,20 +2043,17 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
}
}
#endif
- if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) {
+
+ if(ssl_cafile || ssl_capath) {
/* tell SSL where to find CA certificates that are used to verify
the servers certificate. */
- if(!SSL_CTX_load_verify_locations(connssl->ctx,
- data->set.str[STRING_SSL_CAFILE],
- data->set.str[STRING_SSL_CAPATH])) {
- if(data->set.ssl.verifypeer) {
+ if(!SSL_CTX_load_verify_locations(connssl->ctx, ssl_cafile, ssl_capath)) {
+ if(verifypeer) {
/* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate verify locations:\n"
" CAfile: %s\n CApath: %s",
- data->set.str[STRING_SSL_CAFILE]?
- data->set.str[STRING_SSL_CAFILE]: "none",
- data->set.str[STRING_SSL_CAPATH]?
- data->set.str[STRING_SSL_CAPATH] : "none");
+ ssl_cafile ? ssl_cafile : "none",
+ ssl_capath ? ssl_capath : "none");
return CURLE_SSL_CACERT_BADFILE;
}
else {
@@ -2052,10 +2070,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
infof(data,
" CAfile: %s\n"
" CApath: %s\n",
- data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
- "none",
- data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
- "none");
+ ssl_cafile ? ssl_cafile : "none",
+ ssl_capath ? ssl_capath : "none");
}
#ifdef CURL_CA_FALLBACK
else if(data->set.ssl.verifypeer) {
@@ -2065,16 +2081,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
}
#endif
- if(data->set.str[STRING_SSL_CRLFILE]) {
+ if(ssl_crlfile) {
/* tell SSL where to find CRL file that is used to check certificate
* revocation */
lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx),
X509_LOOKUP_file());
if(!lookup ||
- (!X509_load_crl_file(lookup, data->set.str[STRING_SSL_CRLFILE],
- X509_FILETYPE_PEM)) ) {
- failf(data, "error loading CRL file: %s",
- data->set.str[STRING_SSL_CRLFILE]);
+ (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) {
+ failf(data, "error loading CRL file: %s", ssl_crlfile);
return CURLE_SSL_CRL_BADFILE;
}
else {
@@ -2083,9 +2097,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
}
- infof(data,
- " CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
- data->set.str[STRING_SSL_CRLFILE]: "none");
+ infof(data, " CRLfile: %s\n", ssl_crlfile ? ssl_crlfile: "none");
}
/* Try building a chain using issuers in the trusted store first to avoid
@@ -2107,8 +2119,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
* anyway. In the latter case the result of the verification is checked with
* SSL_get_verify_result() below. */
SSL_CTX_set_verify(connssl->ctx,
- data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
- NULL);
+ verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
/* give application a chance to interfere with SSL set up. */
if(data->set.ssl.fsslctx) {
@@ -2131,31 +2142,30 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
!defined(OPENSSL_NO_OCSP)
- if(data->set.ssl.verifystatus)
+ if(SSL_CONN_CONFIG(verifystatus))
SSL_set_tlsext_status_type(connssl->handle, TLSEXT_STATUSTYPE_ocsp);
#endif
SSL_set_connect_state(connssl->handle);
connssl->server_cert = 0x0;
-
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
- if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
+ if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
#ifdef ENABLE_IPV6
- (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
+ (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
#endif
sni &&
- !SSL_set_tlsext_host_name(connssl->handle, conn->host.name))
+ !SSL_set_tlsext_host_name(connssl->handle, hostname))
infof(data, "WARNING: failed to configure server name indication (SNI) "
"TLS extension\n");
#endif
/* Check if there's a cached ID we can/should use here! */
- if(conn->ssl_config.sessionid) {
+ if(data->set.general_ssl.sessionid) {
void *ssl_sessionid = NULL;
Curl_ssl_sessionid_lock(conn);
- if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
+ if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
/* we got a session id, use it! */
if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
Curl_ssl_sessionid_unlock(conn);
@@ -2169,8 +2179,16 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
Curl_ssl_sessionid_unlock(conn);
}
- /* pass the raw socket into the SSL layers */
- if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
+ if(conn->proxy_ssl[sockindex].use) {
+ BIO *const bio = BIO_new(BIO_f_ssl());
+ DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
+ DEBUGASSERT(conn->proxy_ssl[sockindex].handle != NULL);
+ DEBUGASSERT(bio != NULL);
+ BIO_set_ssl(bio, conn->proxy_ssl[sockindex].handle, FALSE);
+ SSL_set_bio(connssl->handle, bio, bio);
+ }
+ else if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
+ /* pass the raw socket into the SSL layers */
failf(data, "SSL: SSL_set_fd failed: %s",
ERR_error_string(ERR_get_error(), NULL));
return CURLE_SSL_CONNECT_ERROR;
@@ -2187,8 +2205,8 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
int err;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
- || ssl_connect_2_reading == connssl->connecting_state
- || ssl_connect_2_writing == connssl->connecting_state);
+ || ssl_connect_2_reading == connssl->connecting_state
+ || ssl_connect_2_writing == connssl->connecting_state);
ERR_clear_error();
@@ -2257,8 +2275,11 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
* the SO_ERROR is also lost.
*/
if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
+ const char * const hostname = SSL_IS_PROXY() ?
+ conn->http_proxy.host.name : conn->host.name;
+ const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
- conn->host.name, conn->remote_port);
+ hostname, port);
return result;
}
@@ -2735,6 +2756,8 @@ static CURLcode servercert(struct connectdata *conn,
FILE *fp;
char *buffer = data->state.buffer;
const char *ptr;
+ long * const certverifyresult = SSL_IS_PROXY() ?
+ &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
BIO *mem = BIO_new(BIO_s_mem());
if(data->set.ssl.certinfo)
@@ -2750,7 +2773,7 @@ static CURLcode servercert(struct connectdata *conn,
return CURLE_PEER_FAILED_VERIFICATION;
}
- infof(data, "Server certificate:\n");
+ infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server");
rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
buffer, BUFSIZE);
@@ -2768,7 +2791,7 @@ static CURLcode servercert(struct connectdata *conn,
BIO_free(mem);
- if(data->set.ssl.verifyhost) {
+ if(SSL_CONN_CONFIG(verifyhost)) {
result = verifyhost(conn, connssl->server_cert);
if(result) {
X509_free(connssl->server_cert);
@@ -2791,12 +2814,12 @@ static CURLcode servercert(struct connectdata *conn,
deallocating the certificate. */
/* e.g. match issuer name with provided issuer certificate */
- if(data->set.str[STRING_SSL_ISSUERCERT]) {
- fp = fopen(data->set.str[STRING_SSL_ISSUERCERT], FOPEN_READTEXT);
+ if(SSL_SET_OPTION(issuercert)) {
+ fp = fopen(SSL_SET_OPTION(issuercert), FOPEN_READTEXT);
if(!fp) {
if(strict)
failf(data, "SSL: Unable to open issuer cert (%s)",
- data->set.str[STRING_SSL_ISSUERCERT]);
+ SSL_SET_OPTION(issuercert));
X509_free(connssl->server_cert);
connssl->server_cert = NULL;
return CURLE_SSL_ISSUER_ERROR;
@@ -2806,7 +2829,7 @@ static CURLcode servercert(struct connectdata *conn,
if(!issuer) {
if(strict)
failf(data, "SSL: Unable to read issuer cert (%s)",
- data->set.str[STRING_SSL_ISSUERCERT]);
+ SSL_SET_OPTION(issuercert));
X509_free(connssl->server_cert);
X509_free(issuer);
fclose(fp);
@@ -2818,7 +2841,7 @@ static CURLcode servercert(struct connectdata *conn,
if(X509_check_issued(issuer, connssl->server_cert) != X509_V_OK) {
if(strict)
failf(data, "SSL: Certificate issuer check failed (%s)",
- data->set.str[STRING_SSL_ISSUERCERT]);
+ SSL_SET_OPTION(issuercert));
X509_free(connssl->server_cert);
X509_free(issuer);
connssl->server_cert = NULL;
@@ -2826,15 +2849,14 @@ static CURLcode servercert(struct connectdata *conn,
}
infof(data, " SSL certificate issuer check ok (%s)\n",
- data->set.str[STRING_SSL_ISSUERCERT]);
+ SSL_SET_OPTION(issuercert));
X509_free(issuer);
}
- lerr = data->set.ssl.certverifyresult =
- SSL_get_verify_result(connssl->handle);
+ lerr = *certverifyresult = SSL_get_verify_result(connssl->handle);
- if(data->set.ssl.certverifyresult != X509_V_OK) {
- if(data->set.ssl.verifypeer) {
+ if(*certverifyresult != X509_V_OK) {
+ if(SSL_CONN_CONFIG(verifypeer)) {
/* We probably never reach this, because SSL_connect() will fail
and we return earlier if verifypeer is set? */
if(strict)
@@ -2853,7 +2875,7 @@ static CURLcode servercert(struct connectdata *conn,
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
!defined(OPENSSL_NO_OCSP)
- if(data->set.ssl.verifystatus) {
+ if(SSL_CONN_CONFIG(verifystatus)) {
result = verifystatus(conn, connssl);
if(result) {
X509_free(connssl->server_cert);
@@ -2889,7 +2911,7 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
- if(conn->ssl_config.sessionid) {
+ if(data->set.general_ssl.sessionid) {
bool incache;
SSL_SESSION *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
@@ -2901,7 +2923,8 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
regardless of its state. */
Curl_ssl_sessionid_lock(conn);
- incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+ incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
+ sockindex));
if(incache) {
if(old_ssl_sessionid != our_ssl_sessionid) {
infof(data, "old SSL session ID is stale, removing\n");
@@ -2912,7 +2935,7 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
if(!incache) {
result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
- 0 /* unknown size */);
+ 0 /* unknown size */, sockindex);
if(result) {
Curl_ssl_sessionid_unlock(conn);
failf(data, "failed to store ssl session");
@@ -2936,8 +2959,8 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
* operations.
*/
- result = servercert(conn, connssl,
- (data->set.ssl.verifypeer || data->set.ssl.verifyhost));
+ result = servercert(conn, connssl, (SSL_CONN_CONFIG(verifypeer) ||
+ SSL_CONN_CONFIG(verifyhost)));
if(!result)
connssl->connecting_state = ssl_connect_done;
@@ -3085,7 +3108,10 @@ bool Curl_ossl_data_pending(const struct connectdata *conn, int connindex)
{
if(conn->ssl[connindex].handle)
/* SSL is in use */
- return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
+ return (0 != SSL_pending(conn->ssl[connindex].handle) ||
+ (conn->proxy_ssl[connindex].handle &&
+ 0 != SSL_pending(conn->proxy_ssl[connindex].handle))) ?
+ TRUE : FALSE;
else
return FALSE;
}
@@ -3130,8 +3156,18 @@ static ssize_t ossl_send(struct connectdata *conn,
/* A failure in the SSL library occurred, usually a protocol error.
The OpenSSL error queue contains more information on the error. */
sslerror = ERR_get_error();
- failf(conn->data, "SSL_write() error: %s",
- ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
+ if(sslerror ==
+ ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET) &&
+ conn->ssl[sockindex].state == ssl_connection_complete &&
+ conn->proxy_ssl[sockindex].state == ssl_connection_complete) {
+ char ver[120];
+ Curl_ossl_version(ver, 120);
+ failf(conn->data, "Error: %s does not support double SSL tunneling.",
+ ver);
+ }
+ else
+ failf(conn->data, "SSL_write() error: %s",
+ ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
*curlcode = CURLE_SEND_ERROR;
return -1;
}