mirror of
https://github.com/curl/curl.git
synced 2024-12-09 06:30:06 +08:00
vtls: prepare the SSL backends for encapsulated private data
At the moment, cURL's SSL backend needs to be configured at build time. As such, it is totally okay for them to hard-code their backend-specific data in the ssl_connect_data struct. In preparation for making the SSL backend a runtime option, let's make the access of said private data a bit more abstract so that it can be adjusted later in an easy manner. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
parent
20c6cf7e95
commit
d65e6cc4fc
@ -47,6 +47,8 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
static CURLcode map_error_to_curl(int axtls_err)
|
||||
{
|
||||
switch(axtls_err) {
|
||||
@ -104,13 +106,13 @@ static Curl_send axtls_send;
|
||||
|
||||
static void free_ssl_structs(struct ssl_connect_data *connssl)
|
||||
{
|
||||
if(connssl->ssl) {
|
||||
ssl_free(connssl->ssl);
|
||||
connssl->ssl = NULL;
|
||||
if(BACKEND->ssl) {
|
||||
ssl_free(BACKEND->ssl);
|
||||
BACKEND->ssl = NULL;
|
||||
}
|
||||
if(connssl->ssl_ctx) {
|
||||
ssl_ctx_free(connssl->ssl_ctx);
|
||||
connssl->ssl_ctx = NULL;
|
||||
if(BACKEND->ssl_ctx) {
|
||||
ssl_ctx_free(BACKEND->ssl_ctx);
|
||||
BACKEND->ssl_ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,6 +123,7 @@ static void free_ssl_structs(struct ssl_connect_data *connssl)
|
||||
*/
|
||||
static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct Curl_easy *data = conn->data;
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL *ssl = NULL;
|
||||
@ -135,7 +138,7 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
SSL_SERVER_VERIFY_LATER |
|
||||
SSL_CONNECT_IN_PARTS;
|
||||
|
||||
if(conn->ssl[sockindex].state == ssl_connection_complete)
|
||||
if(connssl->state == ssl_connection_complete)
|
||||
/* to make us tolerant against being called more than once for the
|
||||
same connection */
|
||||
return CURLE_OK;
|
||||
@ -169,8 +172,8 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
conn->ssl[sockindex].ssl_ctx = ssl_ctx;
|
||||
conn->ssl[sockindex].ssl = NULL;
|
||||
BACKEND->ssl_ctx = ssl_ctx;
|
||||
BACKEND->ssl = NULL;
|
||||
|
||||
/* Load the trusted CA cert bundle file */
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
@ -265,7 +268,7 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
if(!ssl)
|
||||
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0, NULL);
|
||||
|
||||
conn->ssl[sockindex].ssl = ssl;
|
||||
BACKEND->ssl = ssl;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -275,7 +278,7 @@ static void Curl_axtls_close(struct connectdata *conn, int sockindex)
|
||||
|
||||
infof(conn->data, " Curl_axtls_close\n");
|
||||
|
||||
/* line from openssl.c: (void)SSL_shutdown(connssl->ssl);
|
||||
/* line from openssl.c: (void)SSL_shutdown(BACKEND->ssl);
|
||||
axTLS compat layer does nothing for SSL_shutdown */
|
||||
|
||||
/* The following line is from openssl.c. There seems to be no axTLS
|
||||
@ -292,7 +295,8 @@ static void Curl_axtls_close(struct connectdata *conn, int sockindex)
|
||||
static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
SSL *ssl = conn->ssl[sockindex].ssl;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
SSL *ssl = BACKEND->ssl;
|
||||
const char *peer_CN;
|
||||
uint32_t dns_altname_index;
|
||||
const char *dns_altname;
|
||||
@ -387,7 +391,7 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* General housekeeping */
|
||||
conn->ssl[sockindex].state = ssl_connection_complete;
|
||||
connssl->state = ssl_connection_complete;
|
||||
conn->recv[sockindex] = axtls_recv;
|
||||
conn->send[sockindex] = axtls_send;
|
||||
|
||||
@ -412,6 +416,7 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
static CURLcode Curl_axtls_connect_nonblocking(struct connectdata *conn,
|
||||
int sockindex, bool *done)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
CURLcode conn_step;
|
||||
int ssl_fcn_return;
|
||||
int i;
|
||||
@ -419,23 +424,23 @@ static CURLcode Curl_axtls_connect_nonblocking(struct connectdata *conn,
|
||||
*done = FALSE;
|
||||
/* connectdata is calloc'd and connecting_state is only changed in this
|
||||
function, so this is safe, as the state is effectively initialized. */
|
||||
if(conn->ssl[sockindex].connecting_state == ssl_connect_1) {
|
||||
if(connssl->connecting_state == ssl_connect_1) {
|
||||
conn_step = connect_prep(conn, sockindex);
|
||||
if(conn_step != CURLE_OK) {
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
return conn_step;
|
||||
}
|
||||
conn->ssl[sockindex].connecting_state = ssl_connect_2;
|
||||
connssl->connecting_state = ssl_connect_2;
|
||||
}
|
||||
|
||||
if(conn->ssl[sockindex].connecting_state == ssl_connect_2) {
|
||||
if(connssl->connecting_state == ssl_connect_2) {
|
||||
/* Check to make sure handshake was ok. */
|
||||
if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) {
|
||||
if(ssl_handshake_status(BACKEND->ssl) != SSL_OK) {
|
||||
/* Loop to perform more work in between sleeps. This is work around the
|
||||
fact that axtls does not expose any knowledge about when work needs
|
||||
to be performed. This can save ~25% of time on SSL handshakes. */
|
||||
for(i=0; i<5; i++) {
|
||||
ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL);
|
||||
ssl_fcn_return = ssl_read(BACKEND->ssl, NULL);
|
||||
if(ssl_fcn_return < 0) {
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
|
||||
@ -445,10 +450,10 @@ static CURLcode Curl_axtls_connect_nonblocking(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
infof(conn->data, "handshake completed successfully\n");
|
||||
conn->ssl[sockindex].connecting_state = ssl_connect_3;
|
||||
connssl->connecting_state = ssl_connect_3;
|
||||
}
|
||||
|
||||
if(conn->ssl[sockindex].connecting_state == ssl_connect_3) {
|
||||
if(connssl->connecting_state == ssl_connect_3) {
|
||||
conn_step = connect_finish(conn, sockindex);
|
||||
if(conn_step != CURLE_OK) {
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
@ -456,15 +461,15 @@ static CURLcode Curl_axtls_connect_nonblocking(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Reset connect state */
|
||||
conn->ssl[sockindex].connecting_state = ssl_connect_1;
|
||||
connssl->connecting_state = ssl_connect_1;
|
||||
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Unrecognized state. Things are very bad. */
|
||||
conn->ssl[sockindex].state = ssl_connection_none;
|
||||
conn->ssl[sockindex].connecting_state = ssl_connect_1;
|
||||
connssl->state = ssl_connection_none;
|
||||
connssl->connecting_state = ssl_connect_1;
|
||||
/* Return value perhaps not strictly correct, but distinguishes the issue.*/
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
@ -479,7 +484,8 @@ static CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex)
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode conn_step = connect_prep(conn, sockindex);
|
||||
int ssl_fcn_return;
|
||||
SSL *ssl = conn->ssl[sockindex].ssl;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
SSL *ssl = BACKEND->ssl;
|
||||
long timeout_ms;
|
||||
|
||||
if(conn_step != CURLE_OK) {
|
||||
@ -525,8 +531,9 @@ static ssize_t axtls_send(struct connectdata *conn,
|
||||
size_t len,
|
||||
CURLcode *err)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
/* ssl_write() returns 'int' while write() and send() returns 'size_t' */
|
||||
int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len);
|
||||
int rc = ssl_write(BACKEND->ssl, mem, (int)len);
|
||||
|
||||
infof(conn->data, " axtls_send\n");
|
||||
|
||||
@ -563,17 +570,17 @@ static int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
|
||||
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
|
||||
(void)SSL_shutdown(connssl->ssl);
|
||||
(void)SSL_shutdown(BACKEND->ssl);
|
||||
*/
|
||||
|
||||
if(connssl->ssl) {
|
||||
if(BACKEND->ssl) {
|
||||
int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
|
||||
if(what > 0) {
|
||||
/* Something to read, let's do it and hope that it is the close
|
||||
notify alert from the server. buf is managed internally by
|
||||
axTLS and will be released upon calling ssl_free via
|
||||
free_ssl_structs. */
|
||||
nread = (ssize_t)ssl_read(connssl->ssl, &buf);
|
||||
nread = (ssize_t)ssl_read(BACKEND->ssl, &buf);
|
||||
|
||||
if(nread < SSL_OK) {
|
||||
failf(data, "close notify alert not received during shutdown");
|
||||
@ -609,7 +616,7 @@ static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
|
||||
|
||||
*err = CURLE_OK;
|
||||
if(connssl) {
|
||||
ret = ssl_read(connssl->ssl, &read_buf);
|
||||
ret = ssl_read(BACKEND->ssl, &read_buf);
|
||||
if(ret > SSL_OK) {
|
||||
/* ssl_read returns SSL_OK if there is more data to read, so if it is
|
||||
larger, then all data has been read already. */
|
||||
@ -644,7 +651,8 @@ static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
|
||||
*/
|
||||
static int Curl_axtls_check_cxn(struct connectdata *conn)
|
||||
{
|
||||
/* openssl.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1);
|
||||
/* openssl.c line:
|
||||
rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1);
|
||||
axTLS compat layer always returns the last argument, so connection is
|
||||
always alive? */
|
||||
|
||||
@ -685,7 +693,7 @@ static void *Curl_axtls_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return connssl->ssl;
|
||||
return BACKEND->ssl;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_axtls = {
|
||||
|
@ -122,6 +122,8 @@ and that's a problem since options.h hasn't been included yet. */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
static Curl_recv cyassl_recv;
|
||||
static Curl_send cyassl_send;
|
||||
|
||||
@ -148,7 +150,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
char error_buffer[CYASSL_MAX_ERROR_SZ];
|
||||
char *ciphers;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data* conssl = &conn->ssl[sockindex];
|
||||
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
|
||||
SSL_METHOD* req_method = NULL;
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
#ifdef HAVE_SNI
|
||||
@ -158,7 +160,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
#define use_sni(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
if(conssl->state == ssl_connection_complete)
|
||||
if(connssl->state == ssl_connection_complete)
|
||||
return CURLE_OK;
|
||||
|
||||
if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
|
||||
@ -217,11 +219,11 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(conssl->ctx)
|
||||
SSL_CTX_free(conssl->ctx);
|
||||
conssl->ctx = SSL_CTX_new(req_method);
|
||||
if(BACKEND->ctx)
|
||||
SSL_CTX_free(BACKEND->ctx);
|
||||
BACKEND->ctx = SSL_CTX_new(req_method);
|
||||
|
||||
if(!conssl->ctx) {
|
||||
if(!BACKEND->ctx) {
|
||||
failf(data, "SSL: couldn't create a context!");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -237,9 +239,9 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
version. We use wolfSSL_CTX_SetMinVersion and not CyaSSL_SetMinVersion
|
||||
because only the former will work before the user's CTX callback is called.
|
||||
*/
|
||||
if((wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1) != 1) &&
|
||||
(wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_1) != 1) &&
|
||||
(wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_2) != 1)) {
|
||||
if((wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1) != 1) &&
|
||||
(wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_1) != 1) &&
|
||||
(wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_2) != 1)) {
|
||||
failf(data, "SSL: couldn't set the minimum protocol version");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
@ -249,7 +251,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
|
||||
ciphers = SSL_CONN_CONFIG(cipher_list);
|
||||
if(ciphers) {
|
||||
if(!SSL_CTX_set_cipher_list(conssl->ctx, ciphers)) {
|
||||
if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
|
||||
failf(data, "failed setting cipher list: %s", ciphers);
|
||||
return CURLE_SSL_CIPHER;
|
||||
}
|
||||
@ -259,7 +261,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
#ifndef NO_FILESYSTEM
|
||||
/* load trusted cacert */
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
if(1 != SSL_CTX_load_verify_locations(conssl->ctx,
|
||||
if(1 != SSL_CTX_load_verify_locations(BACKEND->ctx,
|
||||
SSL_CONN_CONFIG(CAfile),
|
||||
SSL_CONN_CONFIG(CApath))) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
@ -296,7 +298,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
|
||||
int file_type = do_file_type(SSL_SET_OPTION(cert_type));
|
||||
|
||||
if(SSL_CTX_use_certificate_file(conssl->ctx, SSL_SET_OPTION(cert),
|
||||
if(SSL_CTX_use_certificate_file(BACKEND->ctx, SSL_SET_OPTION(cert),
|
||||
file_type) != 1) {
|
||||
failf(data, "unable to use client certificate (no key or wrong pass"
|
||||
" phrase?)");
|
||||
@ -304,7 +306,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
file_type = do_file_type(SSL_SET_OPTION(key_type));
|
||||
if(SSL_CTX_use_PrivateKey_file(conssl->ctx, SSL_SET_OPTION(key),
|
||||
if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
|
||||
file_type) != 1) {
|
||||
failf(data, "unable to set private key");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@ -316,7 +318,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
* fail to connect if the verification fails, or if it should continue
|
||||
* anyway. In the latter case the result of the verification is checked with
|
||||
* SSL_get_verify_result() below. */
|
||||
SSL_CTX_set_verify(conssl->ctx,
|
||||
SSL_CTX_set_verify(BACKEND->ctx,
|
||||
SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER:
|
||||
SSL_VERIFY_NONE,
|
||||
NULL);
|
||||
@ -335,7 +337,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
#ifdef ENABLE_IPV6
|
||||
(0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) &&
|
||||
#endif
|
||||
(CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, hostname,
|
||||
(CyaSSL_CTX_UseSNI(BACKEND->ctx, CYASSL_SNI_HOST_NAME, hostname,
|
||||
(unsigned short)hostname_len) != 1)) {
|
||||
infof(data, "WARNING: failed to configure server name indication (SNI) "
|
||||
"TLS extension\n");
|
||||
@ -348,15 +350,15 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
https://github.com/wolfSSL/wolfssl/issues/366
|
||||
The supported curves below are those also supported by OpenSSL 1.0.2 and
|
||||
in the same order. */
|
||||
CyaSSL_CTX_UseSupportedCurve(conssl->ctx, 0x17); /* secp256r1 */
|
||||
CyaSSL_CTX_UseSupportedCurve(conssl->ctx, 0x19); /* secp521r1 */
|
||||
CyaSSL_CTX_UseSupportedCurve(conssl->ctx, 0x18); /* secp384r1 */
|
||||
CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x17); /* secp256r1 */
|
||||
CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x19); /* secp521r1 */
|
||||
CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x18); /* secp384r1 */
|
||||
#endif
|
||||
|
||||
/* give application a chance to interfere with SSL set up. */
|
||||
if(data->set.ssl.fsslctx) {
|
||||
CURLcode result = CURLE_OK;
|
||||
result = (*data->set.ssl.fsslctx)(data, conssl->ctx,
|
||||
result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
|
||||
data->set.ssl.fsslctxp);
|
||||
if(result) {
|
||||
failf(data, "error signaled by ssl ctx callback");
|
||||
@ -374,10 +376,10 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
/* Let's make an SSL structure */
|
||||
if(conssl->handle)
|
||||
SSL_free(conssl->handle);
|
||||
conssl->handle = SSL_new(conssl->ctx);
|
||||
if(!conssl->handle) {
|
||||
if(BACKEND->handle)
|
||||
SSL_free(BACKEND->handle);
|
||||
BACKEND->handle = SSL_new(BACKEND->ctx);
|
||||
if(!BACKEND->handle) {
|
||||
failf(data, "SSL: couldn't create a context (handle)!");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -400,7 +402,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1);
|
||||
infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
|
||||
|
||||
if(wolfSSL_UseALPN(conssl->handle, protocols,
|
||||
if(wolfSSL_UseALPN(BACKEND->handle, protocols,
|
||||
(unsigned)strlen(protocols),
|
||||
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) {
|
||||
failf(data, "SSL: failed setting ALPN protocols");
|
||||
@ -416,10 +418,10 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
|
||||
/* we got a session id, use it! */
|
||||
if(!SSL_set_session(conssl->handle, ssl_sessionid)) {
|
||||
if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
failf(data, "SSL: SSL_set_session failed: %s",
|
||||
ERR_error_string(SSL_get_error(conssl->handle, 0),
|
||||
ERR_error_string(SSL_get_error(BACKEND->handle, 0),
|
||||
error_buffer));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
@ -430,12 +432,12 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* pass the raw socket into the SSL layer */
|
||||
if(!SSL_set_fd(conssl->handle, (int)sockfd)) {
|
||||
if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) {
|
||||
failf(data, "SSL: SSL_set_fd failed");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
conssl->connecting_state = ssl_connect_2;
|
||||
connssl->connecting_state = ssl_connect_2;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -446,7 +448,7 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
{
|
||||
int ret = -1;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data* conssl = &conn->ssl[sockindex];
|
||||
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const char * const dispname = SSL_IS_PROXY() ?
|
||||
@ -460,22 +462,22 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
|
||||
/* Enable RFC2818 checks */
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
ret = CyaSSL_check_domain_name(conssl->handle, hostname);
|
||||
ret = CyaSSL_check_domain_name(BACKEND->handle, hostname);
|
||||
if(ret == SSL_FAILURE)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
ret = SSL_connect(conssl->handle);
|
||||
ret = SSL_connect(BACKEND->handle);
|
||||
if(ret != 1) {
|
||||
char error_buffer[CYASSL_MAX_ERROR_SZ];
|
||||
int detail = SSL_get_error(conssl->handle, ret);
|
||||
int detail = SSL_get_error(BACKEND->handle, ret);
|
||||
|
||||
if(SSL_ERROR_WANT_READ == detail) {
|
||||
conssl->connecting_state = ssl_connect_2_reading;
|
||||
connssl->connecting_state = ssl_connect_2_reading;
|
||||
return CURLE_OK;
|
||||
}
|
||||
else if(SSL_ERROR_WANT_WRITE == detail) {
|
||||
conssl->connecting_state = ssl_connect_2_writing;
|
||||
connssl->connecting_state = ssl_connect_2_writing;
|
||||
return CURLE_OK;
|
||||
}
|
||||
/* There is no easy way to override only the CN matching.
|
||||
@ -536,7 +538,7 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
curl_asn1Element *pubkey;
|
||||
CURLcode result;
|
||||
|
||||
x509 = SSL_get_peer_certificate(conssl->handle);
|
||||
x509 = SSL_get_peer_certificate(BACKEND->handle);
|
||||
if(!x509) {
|
||||
failf(data, "SSL: failed retrieving server certificate");
|
||||
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||
@ -578,7 +580,7 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
char *protocol = NULL;
|
||||
unsigned short protocol_len = 0;
|
||||
|
||||
rc = wolfSSL_ALPN_GetProtocol(conssl->handle, &protocol, &protocol_len);
|
||||
rc = wolfSSL_ALPN_GetProtocol(BACKEND->handle, &protocol, &protocol_len);
|
||||
|
||||
if(rc == SSL_SUCCESS) {
|
||||
infof(data, "ALPN, server accepted to use %.*s\n", protocol_len,
|
||||
@ -607,11 +609,11 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
}
|
||||
#endif /* HAVE_ALPN */
|
||||
|
||||
conssl->connecting_state = ssl_connect_3;
|
||||
connssl->connecting_state = ssl_connect_3;
|
||||
#if (LIBCYASSL_VERSION_HEX >= 0x03009010)
|
||||
infof(data, "SSL connection using %s / %s\n",
|
||||
wolfSSL_get_version(conssl->handle),
|
||||
wolfSSL_get_cipher_name(conssl->handle));
|
||||
wolfSSL_get_version(BACKEND->handle),
|
||||
wolfSSL_get_cipher_name(BACKEND->handle));
|
||||
#else
|
||||
infof(data, "SSL connected\n");
|
||||
#endif
|
||||
@ -635,7 +637,7 @@ cyassl_connect_step3(struct connectdata *conn,
|
||||
SSL_SESSION *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
|
||||
our_ssl_sessionid = SSL_get_session(connssl->handle);
|
||||
our_ssl_sessionid = SSL_get_session(BACKEND->handle);
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
|
||||
@ -672,12 +674,13 @@ static ssize_t cyassl_send(struct connectdata *conn,
|
||||
size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
char error_buffer[CYASSL_MAX_ERROR_SZ];
|
||||
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
|
||||
int rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
|
||||
int rc = SSL_write(BACKEND->handle, mem, memlen);
|
||||
|
||||
if(rc < 0) {
|
||||
int err = SSL_get_error(conn->ssl[sockindex].handle, rc);
|
||||
int err = SSL_get_error(BACKEND->handle, rc);
|
||||
|
||||
switch(err) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
@ -698,16 +701,16 @@ static ssize_t cyassl_send(struct connectdata *conn,
|
||||
|
||||
static void Curl_cyassl_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *conssl = &conn->ssl[sockindex];
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
if(conssl->handle) {
|
||||
(void)SSL_shutdown(conssl->handle);
|
||||
SSL_free(conssl->handle);
|
||||
conssl->handle = NULL;
|
||||
if(BACKEND->handle) {
|
||||
(void)SSL_shutdown(BACKEND->handle);
|
||||
SSL_free(BACKEND->handle);
|
||||
BACKEND->handle = NULL;
|
||||
}
|
||||
if(conssl->ctx) {
|
||||
SSL_CTX_free(conssl->ctx);
|
||||
conssl->ctx = NULL;
|
||||
if(BACKEND->ctx) {
|
||||
SSL_CTX_free(BACKEND->ctx);
|
||||
BACKEND->ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -717,12 +720,13 @@ static ssize_t cyassl_recv(struct connectdata *conn,
|
||||
size_t buffersize,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
char error_buffer[CYASSL_MAX_ERROR_SZ];
|
||||
int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
|
||||
int nread = SSL_read(conn->ssl[num].handle, buf, buffsize);
|
||||
int nread = SSL_read(BACKEND->handle, buf, buffsize);
|
||||
|
||||
if(nread < 0) {
|
||||
int err = SSL_get_error(conn->ssl[num].handle, nread);
|
||||
int err = SSL_get_error(BACKEND->handle, nread);
|
||||
|
||||
switch(err) {
|
||||
case SSL_ERROR_ZERO_RETURN: /* no more data */
|
||||
@ -774,8 +778,9 @@ static int Curl_cyassl_init(void)
|
||||
static bool Curl_cyassl_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;
|
||||
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
|
||||
if(BACKEND->handle) /* SSL is in use */
|
||||
return (0 != SSL_pending(BACKEND->handle)) ? TRUE : FALSE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
@ -790,9 +795,9 @@ static int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex)
|
||||
int retval = 0;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
if(connssl->handle) {
|
||||
SSL_free(connssl->handle);
|
||||
connssl->handle = NULL;
|
||||
if(BACKEND->handle) {
|
||||
SSL_free(BACKEND->handle);
|
||||
BACKEND->handle = NULL;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@ -963,7 +968,7 @@ static void *Curl_cyassl_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return connssl->handle;
|
||||
return BACKEND->handle;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_cyassl = {
|
||||
|
@ -118,6 +118,8 @@
|
||||
#define ioErr -36
|
||||
#define paramErr -50
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
/* pinned public key support tests */
|
||||
|
||||
/* version 1 supports macOS 10.12+ and iOS 10+ */
|
||||
@ -179,7 +181,7 @@ static OSStatus SocketRead(SSLConnectionRef connection,
|
||||
UInt8 *currData = (UInt8 *)data;
|
||||
/*int sock = *(int *)connection;*/
|
||||
struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
|
||||
int sock = connssl->ssl_sockfd;
|
||||
int sock = BACKEND->ssl_sockfd;
|
||||
OSStatus rtn = noErr;
|
||||
size_t bytesRead;
|
||||
ssize_t rrtn;
|
||||
@ -208,7 +210,7 @@ static OSStatus SocketRead(SSLConnectionRef connection,
|
||||
break;
|
||||
case EAGAIN:
|
||||
rtn = errSSLWouldBlock;
|
||||
connssl->ssl_direction = false;
|
||||
BACKEND->ssl_direction = false;
|
||||
break;
|
||||
default:
|
||||
rtn = ioErr;
|
||||
@ -239,7 +241,7 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
|
||||
size_t bytesSent = 0;
|
||||
/*int sock = *(int *)connection;*/
|
||||
struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
|
||||
int sock = connssl->ssl_sockfd;
|
||||
int sock = BACKEND->ssl_sockfd;
|
||||
ssize_t length;
|
||||
size_t dataLen = *dataLength;
|
||||
const UInt8 *dataPtr = (UInt8 *)data;
|
||||
@ -259,7 +261,7 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
|
||||
theErr = errno;
|
||||
if(theErr == EAGAIN) {
|
||||
ortn = errSSLWouldBlock;
|
||||
connssl->ssl_direction = true;
|
||||
BACKEND->ssl_direction = true;
|
||||
}
|
||||
else {
|
||||
ortn = ioErr;
|
||||
@ -1193,30 +1195,30 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
|
||||
return result;
|
||||
}
|
||||
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, darwin_ver_min);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, darwin_ver_max);
|
||||
(void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, darwin_ver_min);
|
||||
(void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, darwin_ver_max);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
#if CURL_SUPPORT_MAC_10_8
|
||||
long i = ssl_version;
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kSSLProtocolAll,
|
||||
false);
|
||||
for(; i <= (ssl_version_max >> 16); i++) {
|
||||
switch(i) {
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kTLSProtocol1,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kTLSProtocol11,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kTLSProtocol12,
|
||||
true);
|
||||
break;
|
||||
@ -1262,10 +1264,10 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
|
||||
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||
if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
|
||||
if(connssl->ssl_ctx)
|
||||
CFRelease(connssl->ssl_ctx);
|
||||
connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
|
||||
if(!connssl->ssl_ctx) {
|
||||
if(BACKEND->ssl_ctx)
|
||||
CFRelease(BACKEND->ssl_ctx);
|
||||
BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
|
||||
if(!BACKEND->ssl_ctx) {
|
||||
failf(data, "SSL: couldn't create a context!");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -1273,9 +1275,9 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
else {
|
||||
/* The old ST API does not exist under iOS, so don't compile it: */
|
||||
#if CURL_SUPPORT_MAC_10_8
|
||||
if(connssl->ssl_ctx)
|
||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||
err = SSLNewContext(false, &(connssl->ssl_ctx));
|
||||
if(BACKEND->ssl_ctx)
|
||||
(void)SSLDisposeContext(BACKEND->ssl_ctx);
|
||||
err = SSLNewContext(false, &(BACKEND->ssl_ctx));
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -1283,15 +1285,15 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||
}
|
||||
#else
|
||||
if(connssl->ssl_ctx)
|
||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||
err = SSLNewContext(false, &(connssl->ssl_ctx));
|
||||
if(BACKEND->ssl_ctx)
|
||||
(void)SSLDisposeContext(BACKEND->ssl_ctx);
|
||||
err = SSLNewContext(false, &(BACKEND->ssl_ctx));
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
|
||||
connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
|
||||
BACKEND->ssl_write_buffered_length = 0UL; /* reset buffered write length */
|
||||
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||
@ -1299,8 +1301,8 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
switch(conn->ssl_config.version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||
(void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
|
||||
(void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
@ -1313,20 +1315,20 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
||||
err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol3);
|
||||
if(err != noErr) {
|
||||
failf(data, "Your version of the OS does not support SSLv3");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
|
||||
(void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol3);
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
|
||||
err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol2);
|
||||
if(err != noErr) {
|
||||
failf(data, "Your version of the OS does not support SSLv2");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
|
||||
(void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol2);
|
||||
break;
|
||||
default:
|
||||
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
||||
@ -1335,19 +1337,19 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
#if CURL_SUPPORT_MAC_10_8
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kSSLProtocolAll,
|
||||
false);
|
||||
switch(conn->ssl_config.version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kTLSProtocol1,
|
||||
true);
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kTLSProtocol11,
|
||||
true);
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kTLSProtocol12,
|
||||
true);
|
||||
break;
|
||||
@ -1362,7 +1364,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kSSLProtocol3,
|
||||
true);
|
||||
if(err != noErr) {
|
||||
@ -1371,7 +1373,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kSSLProtocol2,
|
||||
true);
|
||||
if(err != noErr) {
|
||||
@ -1391,12 +1393,12 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
" SSL/TLS version");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, kSSLProtocolAll, false);
|
||||
switch(conn->ssl_config.version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
(void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kTLSProtocol1,
|
||||
true);
|
||||
break;
|
||||
@ -1410,7 +1412,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
failf(data, "Your version of the OS does not support TLSv1.3");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kSSLProtocol2,
|
||||
true);
|
||||
if(err != noErr) {
|
||||
@ -1419,7 +1421,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
|
||||
kSSLProtocol3,
|
||||
true);
|
||||
if(err != noErr) {
|
||||
@ -1483,7 +1485,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
certs_c[0] = cert_and_key;
|
||||
certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
|
||||
&kCFTypeArrayCallBacks);
|
||||
err = SSLSetCertificate(connssl->ssl_ctx, certs);
|
||||
err = SSLSetCertificate(BACKEND->ssl_ctx, certs);
|
||||
if(certs)
|
||||
CFRelease(certs);
|
||||
if(err != noErr) {
|
||||
@ -1546,7 +1548,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
if(SSLSetSessionOption != NULL) {
|
||||
#endif /* CURL_BUILD_MAC */
|
||||
bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
|
||||
err = SSLSetSessionOption(connssl->ssl_ctx,
|
||||
err = SSLSetSessionOption(BACKEND->ssl_ctx,
|
||||
kSSLSessionOptionBreakOnServerAuth,
|
||||
break_on_auth);
|
||||
if(err != noErr) {
|
||||
@ -1556,7 +1558,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
#if CURL_SUPPORT_MAC_10_8
|
||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||
err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
|
||||
conn->ssl_config.verifypeer?true:false);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
||||
@ -1565,7 +1567,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||
}
|
||||
#else
|
||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||
err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
|
||||
conn->ssl_config.verifypeer?true:false);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
||||
@ -1586,7 +1588,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
* Both hostname check and SNI require SSLSetPeerDomainName().
|
||||
* Also: the verifyhost setting influences SNI usage */
|
||||
if(conn->ssl_config.verifyhost) {
|
||||
err = SSLSetPeerDomainName(connssl->ssl_ctx, hostname,
|
||||
err = SSLSetPeerDomainName(BACKEND->ssl_ctx, hostname,
|
||||
strlen(hostname));
|
||||
|
||||
if(err != noErr) {
|
||||
@ -1612,11 +1614,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
higher priority, but it's probably better that we not connect at all than
|
||||
to give the user a false sense of security if the server only supports
|
||||
insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
|
||||
(void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
|
||||
(void)SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count);
|
||||
all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
|
||||
allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
|
||||
if(all_ciphers && allowed_ciphers &&
|
||||
SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
|
||||
SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers,
|
||||
&all_ciphers_count) == noErr) {
|
||||
for(i = 0UL ; i < all_ciphers_count ; i++) {
|
||||
#if CURL_BUILD_MAC
|
||||
@ -1698,7 +1700,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
}
|
||||
err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
|
||||
err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers,
|
||||
allowed_ciphers_count);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
|
||||
@ -1719,9 +1721,9 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
specifically doesn't want us doing that: */
|
||||
if(SSLSetSessionOption != NULL) {
|
||||
/* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */
|
||||
SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
|
||||
SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
|
||||
!data->set.ssl.enable_beast);
|
||||
SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
|
||||
SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart,
|
||||
data->set.ssl.falsestart); /* false start support */
|
||||
}
|
||||
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
|
||||
@ -1735,7 +1737,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
|
||||
&ssl_sessionid_len, sockindex)) {
|
||||
/* we got a session id, use it! */
|
||||
err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
|
||||
err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
|
||||
@ -1753,7 +1755,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
|
||||
ssl_sessionid_len = strlen(ssl_sessionid);
|
||||
|
||||
err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
|
||||
err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
|
||||
if(err != noErr) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
|
||||
@ -1770,7 +1772,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
|
||||
err = SSLSetIOFuncs(BACKEND->ssl_ctx, SocketRead, SocketWrite);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@ -1780,8 +1782,8 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
/* We need to store the FD in a constant memory address, because
|
||||
* SSLSetConnection() will not copy that address. I've found that
|
||||
* conn->sock[sockindex] may change on its own. */
|
||||
connssl->ssl_sockfd = sockfd;
|
||||
err = SSLSetConnection(connssl->ssl_ctx, connssl);
|
||||
BACKEND->ssl_sockfd = sockfd;
|
||||
err = SSLSetConnection(BACKEND->ssl_ctx, connssl);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetConnection() failed: %d", err);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@ -2189,12 +2191,12 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
|| ssl_connect_2_writing == connssl->connecting_state);
|
||||
|
||||
/* Here goes nothing: */
|
||||
err = SSLHandshake(connssl->ssl_ctx);
|
||||
err = SSLHandshake(BACKEND->ssl_ctx);
|
||||
|
||||
if(err != noErr) {
|
||||
switch(err) {
|
||||
case errSSLWouldBlock: /* they're not done with us yet */
|
||||
connssl->connecting_state = connssl->ssl_direction ?
|
||||
connssl->connecting_state = BACKEND->ssl_direction ?
|
||||
ssl_connect_2_writing : ssl_connect_2_reading;
|
||||
return CURLE_OK;
|
||||
|
||||
@ -2203,7 +2205,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
case -9841:
|
||||
if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
|
||||
int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
|
||||
connssl->ssl_ctx);
|
||||
BACKEND->ssl_ctx);
|
||||
if(res != CURLE_OK)
|
||||
return res;
|
||||
}
|
||||
@ -2281,7 +2283,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
|
||||
#ifdef DARWIN_SSL_PINNEDPUBKEY
|
||||
if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
|
||||
CURLcode result = pkp_pin_peer_pubkey(data, connssl->ssl_ctx,
|
||||
CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
|
||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
|
||||
if(result) {
|
||||
failf(data, "SSL: public key does not match pinned public key!");
|
||||
@ -2291,8 +2293,8 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
#endif /* DARWIN_SSL_PINNEDPUBKEY */
|
||||
|
||||
/* Informational message */
|
||||
(void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
|
||||
(void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
|
||||
(void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher);
|
||||
(void)SSLGetNegotiatedProtocolVersion(BACKEND->ssl_ctx, &protocol);
|
||||
switch(protocol) {
|
||||
case kSSLProtocol2:
|
||||
infof(data, "SSL 2.0 connection using %s\n",
|
||||
@ -2339,13 +2341,13 @@ show_verbose_server_cert(struct connectdata *conn,
|
||||
CFIndex i, count;
|
||||
SecTrustRef trust = NULL;
|
||||
|
||||
if(!connssl->ssl_ctx)
|
||||
if(!BACKEND->ssl_ctx)
|
||||
return;
|
||||
|
||||
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
|
||||
#if CURL_BUILD_IOS
|
||||
#pragma unused(server_certs)
|
||||
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
|
||||
err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
|
||||
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
|
||||
a null trust, so be on guard for that: */
|
||||
if(err == noErr && trust) {
|
||||
@ -2371,7 +2373,7 @@ show_verbose_server_cert(struct connectdata *conn,
|
||||
Lion or later. */
|
||||
if(SecTrustEvaluateAsync != NULL) {
|
||||
#pragma unused(server_certs)
|
||||
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
|
||||
err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
|
||||
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
|
||||
a null trust, so be on guard for that: */
|
||||
if(err == noErr && trust) {
|
||||
@ -2391,7 +2393,7 @@ show_verbose_server_cert(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
#if CURL_SUPPORT_MAC_10_8
|
||||
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
||||
err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
|
||||
/* Just in case SSLCopyPeerCertificates() returns null too... */
|
||||
if(err == noErr && server_certs) {
|
||||
count = CFArrayGetCount(server_certs);
|
||||
@ -2413,7 +2415,7 @@ show_verbose_server_cert(struct connectdata *conn,
|
||||
#endif /* CURL_BUILD_IOS */
|
||||
#else
|
||||
#pragma unused(trust)
|
||||
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
||||
err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
|
||||
if(err == noErr) {
|
||||
count = CFArrayGetCount(server_certs);
|
||||
for(i = 0L ; i < count ; i++) {
|
||||
@ -2593,21 +2595,21 @@ static void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
if(connssl->ssl_ctx) {
|
||||
(void)SSLClose(connssl->ssl_ctx);
|
||||
if(BACKEND->ssl_ctx) {
|
||||
(void)SSLClose(BACKEND->ssl_ctx);
|
||||
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||
if(SSLCreateContext != NULL)
|
||||
CFRelease(connssl->ssl_ctx);
|
||||
CFRelease(BACKEND->ssl_ctx);
|
||||
#if CURL_SUPPORT_MAC_10_8
|
||||
else
|
||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||
(void)SSLDisposeContext(BACKEND->ssl_ctx);
|
||||
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||
#else
|
||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||
(void)SSLDisposeContext(BACKEND->ssl_ctx);
|
||||
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
|
||||
connssl->ssl_ctx = NULL;
|
||||
BACKEND->ssl_ctx = NULL;
|
||||
}
|
||||
connssl->ssl_sockfd = 0;
|
||||
BACKEND->ssl_sockfd = 0;
|
||||
}
|
||||
|
||||
static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
|
||||
@ -2619,7 +2621,7 @@ static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
|
||||
int rc;
|
||||
char buf[120];
|
||||
|
||||
if(!connssl->ssl_ctx)
|
||||
if(!BACKEND->ssl_ctx)
|
||||
return 0;
|
||||
|
||||
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
|
||||
@ -2693,8 +2695,8 @@ static int Curl_darwinssl_check_cxn(struct connectdata *conn)
|
||||
OSStatus err;
|
||||
SSLSessionState state;
|
||||
|
||||
if(connssl->ssl_ctx) {
|
||||
err = SSLGetSessionState(connssl->ssl_ctx, &state);
|
||||
if(BACKEND->ssl_ctx) {
|
||||
err = SSLGetSessionState(BACKEND->ssl_ctx, &state);
|
||||
if(err == noErr)
|
||||
return state == kSSLConnected || state == kSSLHandshake;
|
||||
return -1;
|
||||
@ -2709,8 +2711,8 @@ static bool Curl_darwinssl_data_pending(const struct connectdata *conn,
|
||||
OSStatus err;
|
||||
size_t buffer;
|
||||
|
||||
if(connssl->ssl_ctx) { /* SSL is in use */
|
||||
err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
|
||||
if(BACKEND->ssl_ctx) { /* SSL is in use */
|
||||
err = SSLGetBufferedReadSize(BACKEND->ssl_ctx, &buffer);
|
||||
if(err == noErr)
|
||||
return buffer > 0UL;
|
||||
return false;
|
||||
@ -2791,15 +2793,15 @@ static ssize_t darwinssl_send(struct connectdata *conn,
|
||||
over again with no new data until it quits returning errSSLWouldBlock. */
|
||||
|
||||
/* Do we have buffered data to write from the last time we were called? */
|
||||
if(connssl->ssl_write_buffered_length) {
|
||||
if(BACKEND->ssl_write_buffered_length) {
|
||||
/* Write the buffered data: */
|
||||
err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
|
||||
err = SSLWrite(BACKEND->ssl_ctx, NULL, 0UL, &processed);
|
||||
switch(err) {
|
||||
case noErr:
|
||||
/* processed is always going to be 0 because we didn't write to
|
||||
the buffer, so return how much was written to the socket */
|
||||
processed = connssl->ssl_write_buffered_length;
|
||||
connssl->ssl_write_buffered_length = 0UL;
|
||||
processed = BACKEND->ssl_write_buffered_length;
|
||||
BACKEND->ssl_write_buffered_length = 0UL;
|
||||
break;
|
||||
case errSSLWouldBlock: /* argh, try again */
|
||||
*curlcode = CURLE_AGAIN;
|
||||
@ -2812,13 +2814,13 @@ static ssize_t darwinssl_send(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
/* We've got new data to write: */
|
||||
err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
|
||||
err = SSLWrite(BACKEND->ssl_ctx, mem, len, &processed);
|
||||
if(err != noErr) {
|
||||
switch(err) {
|
||||
case errSSLWouldBlock:
|
||||
/* Data was buffered but not sent, we have to tell the caller
|
||||
to try sending again, and remember how much was buffered */
|
||||
connssl->ssl_write_buffered_length = len;
|
||||
BACKEND->ssl_write_buffered_length = len;
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return -1L;
|
||||
default:
|
||||
@ -2840,7 +2842,7 @@ static ssize_t darwinssl_recv(struct connectdata *conn,
|
||||
/*struct Curl_easy *data = conn->data;*/
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
size_t processed = 0UL;
|
||||
OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
|
||||
OSStatus err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed);
|
||||
|
||||
if(err != noErr) {
|
||||
switch(err) {
|
||||
@ -2875,7 +2877,7 @@ static void *Curl_darwinssl_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return connssl->ssl_ctx;
|
||||
return BACKEND->ssl_ctx;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_darwinssl = {
|
||||
|
123
lib/vtls/gskit.c
123
lib/vtls/gskit.c
@ -98,6 +98,7 @@
|
||||
#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
|
||||
#define CURL_GSKPROTO_LAST 5
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
/* Supported ciphers. */
|
||||
typedef struct {
|
||||
@ -495,14 +496,14 @@ static void cancel_async_handshake(struct connectdata *conn, int sockindex)
|
||||
Qso_OverlappedIO_t cstat;
|
||||
|
||||
if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
|
||||
QsoWaitForIOCompletion(connssl->iocport, &cstat, (struct timeval *) NULL);
|
||||
QsoWaitForIOCompletion(BACKEND->iocport, &cstat, (struct timeval *) NULL);
|
||||
}
|
||||
|
||||
|
||||
static void close_async_handshake(struct ssl_connect_data *connssl)
|
||||
{
|
||||
QsoDestroyIOCompletionPort(connssl->iocport);
|
||||
connssl->iocport = -1;
|
||||
QsoDestroyIOCompletionPort(BACKEND->iocport);
|
||||
BACKEND->iocport = -1;
|
||||
}
|
||||
|
||||
/* SSL over SSL
|
||||
@ -620,12 +621,12 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
|
||||
FD_ZERO(&fds_write);
|
||||
n = -1;
|
||||
if(directions & SOS_READ) {
|
||||
FD_SET(connssl->remotefd, &fds_write);
|
||||
n = connssl->remotefd;
|
||||
FD_SET(BACKEND->remotefd, &fds_write);
|
||||
n = BACKEND->remotefd;
|
||||
}
|
||||
if(directions & SOS_WRITE) {
|
||||
FD_SET(connssl->remotefd, &fds_read);
|
||||
n = connssl->remotefd;
|
||||
FD_SET(BACKEND->remotefd, &fds_read);
|
||||
n = BACKEND->remotefd;
|
||||
FD_SET(conn->sock[sockindex], &fds_write);
|
||||
if(n < conn->sock[sockindex])
|
||||
n = conn->sock[sockindex];
|
||||
@ -634,14 +635,15 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
|
||||
if(i < 0)
|
||||
return -1; /* Select error. */
|
||||
|
||||
if(FD_ISSET(connssl->remotefd, &fds_write)) {
|
||||
if(FD_ISSET(BACKEND->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);
|
||||
i = gsk_secure_soc_read(connproxyssl->handle,
|
||||
buf, sizeof buf, &n);
|
||||
switch(i) {
|
||||
case GSK_OK:
|
||||
if(n) {
|
||||
i = write(connssl->remotefd, buf, n);
|
||||
i = write(BACKEND->remotefd, buf, n);
|
||||
if(i < 0)
|
||||
return -1;
|
||||
ret = 1;
|
||||
@ -655,10 +657,10 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
}
|
||||
|
||||
if(FD_ISSET(connssl->remotefd, &fds_read) &&
|
||||
if(FD_ISSET(BACKEND->remotefd, &fds_read) &&
|
||||
FD_ISSET(conn->sock[sockindex], &fds_write)) {
|
||||
/* Pipe data to HTTPS proxy. */
|
||||
n = read(connssl->remotefd, buf, sizeof buf);
|
||||
n = read(BACKEND->remotefd, buf, sizeof buf);
|
||||
if(n < 0)
|
||||
return -1;
|
||||
if(n) {
|
||||
@ -676,23 +678,23 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
|
||||
static void close_one(struct ssl_connect_data *connssl,
|
||||
struct connectdata *conn, int sockindex)
|
||||
{
|
||||
if(connssl->handle) {
|
||||
gskit_status(conn->data, gsk_secure_soc_close(&connssl->handle),
|
||||
if(BACKEND->handle) {
|
||||
gskit_status(conn->data, gsk_secure_soc_close(&BACKEND->handle),
|
||||
"gsk_secure_soc_close()", 0);
|
||||
/* 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;
|
||||
BACKEND->handle = (gsk_handle) NULL;
|
||||
if(BACKEND->localfd >= 0) {
|
||||
close(BACKEND->localfd);
|
||||
BACKEND->localfd = -1;
|
||||
}
|
||||
if(connssl->remotefd >= 0) {
|
||||
close(connssl->remotefd);
|
||||
connssl->remotefd = -1;
|
||||
if(BACKEND->remotefd >= 0) {
|
||||
close(BACKEND->remotefd);
|
||||
BACKEND->remotefd = -1;
|
||||
}
|
||||
}
|
||||
if(connssl->iocport >= 0)
|
||||
if(BACKEND->iocport >= 0)
|
||||
close_async_handshake(connssl);
|
||||
}
|
||||
|
||||
@ -700,13 +702,14 @@ static void close_one(struct ssl_connect_data *connssl,
|
||||
static ssize_t gskit_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode cc = CURLE_SEND_ERROR;
|
||||
int written;
|
||||
|
||||
if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) >= 0) {
|
||||
cc = gskit_status(data,
|
||||
gsk_secure_soc_write(conn->ssl[sockindex].handle,
|
||||
gsk_secure_soc_write(BACKEND->handle,
|
||||
(char *) mem, (int) len, &written),
|
||||
"gsk_secure_soc_write()", CURLE_SEND_ERROR);
|
||||
if(cc == CURLE_OK)
|
||||
@ -724,6 +727,7 @@ static ssize_t gskit_send(struct connectdata *conn, int sockindex,
|
||||
static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
|
||||
size_t buffersize, CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
struct Curl_easy *data = conn->data;
|
||||
int buffsize;
|
||||
int nread;
|
||||
@ -731,7 +735,7 @@ static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
|
||||
|
||||
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,
|
||||
cc = gskit_status(data, gsk_secure_soc_read(BACKEND->handle,
|
||||
buf, buffsize, &nread),
|
||||
"gsk_secure_soc_read()", CURLE_RECV_ERROR);
|
||||
}
|
||||
@ -806,10 +810,10 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* Create SSL environment, start (preferably asynchronous) handshake. */
|
||||
|
||||
connssl->handle = (gsk_handle) NULL;
|
||||
connssl->iocport = -1;
|
||||
connssl->localfd = -1;
|
||||
connssl->remotefd = -1;
|
||||
BACKEND->handle = (gsk_handle) NULL;
|
||||
BACKEND->iocport = -1;
|
||||
BACKEND->localfd = -1;
|
||||
BACKEND->remotefd = -1;
|
||||
|
||||
/* GSKit supports two ways of specifying an SSL context: either by
|
||||
* application identifier (that should have been defined at the system
|
||||
@ -842,7 +846,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* Create secure session. */
|
||||
result = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
|
||||
result = gskit_status(data, gsk_secure_soc_open(envir, &BACKEND->handle),
|
||||
"gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
|
||||
gsk_environment_close(&envir);
|
||||
if(result)
|
||||
@ -852,18 +856,18 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
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,
|
||||
BACKEND->localfd = sockpair[0];
|
||||
BACKEND->remotefd = sockpair[1];
|
||||
setsockopt(BACKEND->localfd, SOL_SOCKET, SO_RCVBUF,
|
||||
(void *) sobufsize, sizeof sobufsize);
|
||||
setsockopt(connssl->remotefd, SOL_SOCKET, SO_RCVBUF,
|
||||
setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_RCVBUF,
|
||||
(void *) sobufsize, sizeof sobufsize);
|
||||
setsockopt(connssl->localfd, SOL_SOCKET, SO_SNDBUF,
|
||||
setsockopt(BACKEND->localfd, SOL_SOCKET, SO_SNDBUF,
|
||||
(void *) sobufsize, sizeof sobufsize);
|
||||
setsockopt(connssl->remotefd, SOL_SOCKET, SO_SNDBUF,
|
||||
setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_SNDBUF,
|
||||
(void *) sobufsize, sizeof sobufsize);
|
||||
curlx_nonblock(connssl->localfd, TRUE);
|
||||
curlx_nonblock(connssl->remotefd, TRUE);
|
||||
curlx_nonblock(BACKEND->localfd, TRUE);
|
||||
curlx_nonblock(BACKEND->remotefd, TRUE);
|
||||
}
|
||||
|
||||
/* Determine which SSL/TLS version should be enabled. */
|
||||
@ -897,7 +901,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
|
||||
if(sni) {
|
||||
result = set_buffer(data, connssl->handle,
|
||||
result = set_buffer(data, BACKEND->handle,
|
||||
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
|
||||
if(result == CURLE_UNSUPPORTED_PROTOCOL)
|
||||
result = CURLE_OK;
|
||||
@ -911,34 +915,34 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
if(timeout < 0)
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
else
|
||||
result = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
|
||||
result = set_numeric(data, BACKEND->handle, GSK_HANDSHAKE_TIMEOUT,
|
||||
(timeout + 999) / 1000);
|
||||
}
|
||||
if(!result)
|
||||
result = set_numeric(data, connssl->handle, GSK_OS400_READ_TIMEOUT, 1);
|
||||
result = set_numeric(data, BACKEND->handle, GSK_OS400_READ_TIMEOUT, 1);
|
||||
if(!result)
|
||||
result = set_numeric(data, connssl->handle, GSK_FD, connssl->localfd >= 0?
|
||||
connssl->localfd: conn->sock[sockindex]);
|
||||
result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0?
|
||||
BACKEND->localfd: conn->sock[sockindex]);
|
||||
if(!result)
|
||||
result = set_ciphers(conn, connssl->handle, &protoflags);
|
||||
result = set_ciphers(conn, BACKEND->handle, &protoflags);
|
||||
if(!protoflags) {
|
||||
failf(data, "No SSL protocol/cipher combination enabled");
|
||||
result = CURLE_SSL_CIPHER;
|
||||
}
|
||||
if(!result)
|
||||
result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
|
||||
result = set_enum(data, BACKEND->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,
|
||||
result = set_enum(data, BACKEND->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,
|
||||
result = set_enum(data, BACKEND->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,
|
||||
result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV11,
|
||||
(protoflags & CURL_GSKPROTO_TLSV11_MASK)?
|
||||
GSK_TRUE: GSK_FALSE, TRUE);
|
||||
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||
@ -950,7 +954,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
}
|
||||
if(!result) {
|
||||
result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
|
||||
result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV12,
|
||||
(protoflags & CURL_GSKPROTO_TLSV12_MASK)?
|
||||
GSK_TRUE: GSK_FALSE, TRUE);
|
||||
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||
@ -962,18 +966,18 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
}
|
||||
if(!result)
|
||||
result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
|
||||
result = set_enum(data, BACKEND->handle, GSK_SERVER_AUTH_TYPE,
|
||||
verifypeer? GSK_SERVER_AUTH_FULL:
|
||||
GSK_SERVER_AUTH_PASSTHRU, FALSE);
|
||||
|
||||
if(!result) {
|
||||
/* Start handshake. Try asynchronous first. */
|
||||
memset(&commarea, 0, sizeof commarea);
|
||||
connssl->iocport = QsoCreateIOCompletionPort();
|
||||
if(connssl->iocport != -1) {
|
||||
BACKEND->iocport = QsoCreateIOCompletionPort();
|
||||
if(BACKEND->iocport != -1) {
|
||||
result = gskit_status(data,
|
||||
gsk_secure_soc_startInit(connssl->handle,
|
||||
connssl->iocport,
|
||||
gsk_secure_soc_startInit(BACKEND->handle,
|
||||
BACKEND->iocport,
|
||||
&commarea),
|
||||
"gsk_secure_soc_startInit()",
|
||||
CURLE_SSL_CONNECT_ERROR);
|
||||
@ -993,7 +997,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
else {
|
||||
/* No more completion port available. Use synchronous IO. */
|
||||
result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
|
||||
result = gskit_status(data, gsk_secure_soc_init(BACKEND->handle),
|
||||
"gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
|
||||
if(!result) {
|
||||
connssl->connecting_state = ssl_connect_3;
|
||||
@ -1026,7 +1030,7 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
|
||||
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)) {
|
||||
switch(QsoWaitForIOCompletion(BACKEND->iocport, &cstat, &stmv)) {
|
||||
case 1: /* Operation complete. */
|
||||
break;
|
||||
case -1: /* An error occurred: handshake still in progress. */
|
||||
@ -1075,7 +1079,7 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* SSL handshake done: gather certificate info and verify host. */
|
||||
|
||||
if(gskit_status(data, gsk_attribute_get_cert_info(connssl->handle,
|
||||
if(gskit_status(data, gsk_attribute_get_cert_info(BACKEND->handle,
|
||||
GSK_PARTNER_CERT_INFO,
|
||||
&cdev, &cdec),
|
||||
"gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
|
||||
@ -1260,7 +1264,7 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
|
||||
int rc;
|
||||
char buf[120];
|
||||
|
||||
if(!connssl->handle)
|
||||
if(!BACKEND->handle)
|
||||
return 0;
|
||||
|
||||
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
|
||||
@ -1314,12 +1318,13 @@ static size_t Curl_gskit_version(char *buffer, size_t size)
|
||||
|
||||
static int Curl_gskit_check_cxn(struct connectdata *cxn)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &cxn->ssl[FIRSTSOCKET];
|
||||
int err;
|
||||
int errlen;
|
||||
|
||||
/* The only thing that can be tested here is at the socket level. */
|
||||
|
||||
if(!cxn->ssl[FIRSTSOCKET].handle)
|
||||
if(!BACKEND->handle)
|
||||
return 0; /* connection has been closed */
|
||||
|
||||
err = 0;
|
||||
@ -1337,7 +1342,7 @@ static void *Curl_gskit_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return connssl->handle;
|
||||
return BACKEND->handle;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_gskit = {
|
||||
|
@ -107,6 +107,8 @@ static bool gtls_inited = FALSE;
|
||||
# include <gnutls/ocsp.h>
|
||||
#endif
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
/*
|
||||
* Custom push and pull callback functions used by GNU TLS to read and write
|
||||
* to the socket. These functions are simple wrappers to send() and recv()
|
||||
@ -276,7 +278,7 @@ static CURLcode handshake(struct connectdata *conn,
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
gnutls_session_t session = conn->ssl[sockindex].session;
|
||||
gnutls_session_t session = BACKEND->session;
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
time_t timeout_ms;
|
||||
int rc;
|
||||
@ -474,6 +476,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
unsigned int init_flags;
|
||||
gnutls_session_t session;
|
||||
int rc;
|
||||
@ -509,7 +512,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
|
||||
if(conn->ssl[sockindex].state == ssl_connection_complete)
|
||||
if(connssl->state == ssl_connection_complete)
|
||||
/* to make us tolerant against being called more than once for the
|
||||
same connection */
|
||||
return CURLE_OK;
|
||||
@ -525,7 +528,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
sni = FALSE; /* SSLv3 has no SNI */
|
||||
|
||||
/* allocate a cred struct */
|
||||
rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
|
||||
rc = gnutls_certificate_allocate_credentials(&BACKEND->cred);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@ -536,15 +539,14 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username));
|
||||
|
||||
rc = gnutls_srp_allocate_client_credentials(
|
||||
&conn->ssl[sockindex].srp_client_cred);
|
||||
&BACKEND->srp_client_cred);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
|
||||
gnutls_strerror(rc));
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
|
||||
srp_client_cred,
|
||||
rc = gnutls_srp_set_client_credentials(BACKEND->srp_client_cred,
|
||||
SSL_SET_OPTION(username),
|
||||
SSL_SET_OPTION(password));
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
@ -557,10 +559,10 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
/* set the trusted CA cert bundle file */
|
||||
gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
|
||||
gnutls_certificate_set_verify_flags(BACKEND->cred,
|
||||
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
|
||||
|
||||
rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
|
||||
rc = gnutls_certificate_set_x509_trust_file(BACKEND->cred,
|
||||
SSL_CONN_CONFIG(CAfile),
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(rc < 0) {
|
||||
@ -577,7 +579,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
#ifdef HAS_CAPATH
|
||||
if(SSL_CONN_CONFIG(CApath)) {
|
||||
/* set the trusted CA cert directory */
|
||||
rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
|
||||
rc = gnutls_certificate_set_x509_trust_dir(BACKEND->cred,
|
||||
SSL_CONN_CONFIG(CApath),
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(rc < 0) {
|
||||
@ -596,13 +598,13 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
/* use system ca certificate store as fallback */
|
||||
if(SSL_CONN_CONFIG(verifypeer) &&
|
||||
!(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
|
||||
gnutls_certificate_set_x509_system_trust(conn->ssl[sockindex].cred);
|
||||
gnutls_certificate_set_x509_system_trust(BACKEND->cred);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(SSL_SET_OPTION(CRLfile)) {
|
||||
/* set the CRL list file */
|
||||
rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
|
||||
rc = gnutls_certificate_set_x509_crl_file(BACKEND->cred,
|
||||
SSL_SET_OPTION(CRLfile),
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(rc < 0) {
|
||||
@ -623,14 +625,14 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
init_flags |= GNUTLS_NO_TICKETS;
|
||||
#endif
|
||||
|
||||
rc = gnutls_init(&conn->ssl[sockindex].session, init_flags);
|
||||
rc = gnutls_init(&BACKEND->session, init_flags);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_init() failed: %d", rc);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
/* convenient assign */
|
||||
session = conn->ssl[sockindex].session;
|
||||
session = BACKEND->session;
|
||||
|
||||
if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
|
||||
#ifdef ENABLE_IPV6
|
||||
@ -787,7 +789,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
|
||||
GNUTLS_PKCS_USE_PBES2_AES_256;
|
||||
rc = gnutls_certificate_set_x509_key_file2(
|
||||
conn->ssl[sockindex].cred,
|
||||
BACKEND->cred,
|
||||
SSL_SET_OPTION(cert),
|
||||
SSL_SET_OPTION(key) ?
|
||||
SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
|
||||
@ -807,7 +809,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
if(gnutls_certificate_set_x509_key_file(
|
||||
conn->ssl[sockindex].cred,
|
||||
BACKEND->cred,
|
||||
SSL_SET_OPTION(cert),
|
||||
SSL_SET_OPTION(key) ?
|
||||
SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
|
||||
@ -823,7 +825,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
/* put the credentials to the current session */
|
||||
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
|
||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
|
||||
conn->ssl[sockindex].srp_client_cred);
|
||||
BACKEND->srp_client_cred);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@ -833,7 +835,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
#endif
|
||||
{
|
||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
||||
conn->ssl[sockindex].cred);
|
||||
BACKEND->cred);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@ -966,7 +968,8 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
time_t certclock;
|
||||
const char *ptr;
|
||||
struct Curl_easy *data = conn->data;
|
||||
gnutls_session_t session = conn->ssl[sockindex].session;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
gnutls_session_t session = BACKEND->session;
|
||||
int rc;
|
||||
#ifdef HAS_ALPN
|
||||
gnutls_datum_t proto;
|
||||
@ -1516,13 +1519,15 @@ static CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex)
|
||||
static bool Curl_gtls_data_pending(const struct connectdata *conn,
|
||||
int connindex)
|
||||
{
|
||||
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
|
||||
bool res = FALSE;
|
||||
if(conn->ssl[connindex].session &&
|
||||
0 != gnutls_record_check_pending(conn->ssl[connindex].session))
|
||||
if(BACKEND->session &&
|
||||
0 != gnutls_record_check_pending(BACKEND->session))
|
||||
res = TRUE;
|
||||
|
||||
if(conn->proxy_ssl[connindex].session &&
|
||||
0 != gnutls_record_check_pending(conn->proxy_ssl[connindex].session))
|
||||
connssl = &conn->proxy_ssl[connindex];
|
||||
if(BACKEND->session &&
|
||||
0 != gnutls_record_check_pending(BACKEND->session))
|
||||
res = TRUE;
|
||||
|
||||
return res;
|
||||
@ -1534,7 +1539,8 @@ static ssize_t gtls_send(struct connectdata *conn,
|
||||
size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
ssize_t rc = gnutls_record_send(BACKEND->session, mem, len);
|
||||
|
||||
if(rc < 0) {
|
||||
*curlcode = (rc == GNUTLS_E_AGAIN)
|
||||
@ -1547,21 +1553,21 @@ static ssize_t gtls_send(struct connectdata *conn,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void close_one(struct ssl_connect_data *ssl)
|
||||
static void close_one(struct ssl_connect_data *connssl)
|
||||
{
|
||||
if(ssl->session) {
|
||||
gnutls_bye(ssl->session, GNUTLS_SHUT_RDWR);
|
||||
gnutls_deinit(ssl->session);
|
||||
ssl->session = NULL;
|
||||
if(BACKEND->session) {
|
||||
gnutls_bye(BACKEND->session, GNUTLS_SHUT_RDWR);
|
||||
gnutls_deinit(BACKEND->session);
|
||||
BACKEND->session = NULL;
|
||||
}
|
||||
if(ssl->cred) {
|
||||
gnutls_certificate_free_credentials(ssl->cred);
|
||||
ssl->cred = NULL;
|
||||
if(BACKEND->cred) {
|
||||
gnutls_certificate_free_credentials(BACKEND->cred);
|
||||
BACKEND->cred = NULL;
|
||||
}
|
||||
#ifdef USE_TLS_SRP
|
||||
if(ssl->srp_client_cred) {
|
||||
gnutls_srp_free_client_credentials(ssl->srp_client_cred);
|
||||
ssl->srp_client_cred = NULL;
|
||||
if(BACKEND->srp_client_cred) {
|
||||
gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
|
||||
BACKEND->srp_client_cred = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1578,6 +1584,7 @@ static void Curl_gtls_close(struct connectdata *conn, int sockindex)
|
||||
*/
|
||||
static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
ssize_t result;
|
||||
int retval = 0;
|
||||
struct Curl_easy *data = conn->data;
|
||||
@ -1590,16 +1597,16 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
we do not send one. Let's hope other servers do the same... */
|
||||
|
||||
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
|
||||
gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);
|
||||
gnutls_bye(BACKEND->session, GNUTLS_SHUT_WR);
|
||||
|
||||
if(conn->ssl[sockindex].session) {
|
||||
if(BACKEND->session) {
|
||||
while(!done) {
|
||||
int what = SOCKET_READABLE(conn->sock[sockindex],
|
||||
SSL_SHUTDOWN_TIMEOUT);
|
||||
if(what > 0) {
|
||||
/* Something to read, let's do it and hope that it is the close
|
||||
notify alert from the server */
|
||||
result = gnutls_record_recv(conn->ssl[sockindex].session,
|
||||
result = gnutls_record_recv(BACKEND->session,
|
||||
buf, sizeof(buf));
|
||||
switch(result) {
|
||||
case 0:
|
||||
@ -1630,18 +1637,18 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
gnutls_deinit(conn->ssl[sockindex].session);
|
||||
gnutls_deinit(BACKEND->session);
|
||||
}
|
||||
gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
|
||||
gnutls_certificate_free_credentials(BACKEND->cred);
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
|
||||
&& SSL_SET_OPTION(username) != NULL)
|
||||
gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
|
||||
gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
|
||||
#endif
|
||||
|
||||
conn->ssl[sockindex].cred = NULL;
|
||||
conn->ssl[sockindex].session = NULL;
|
||||
BACKEND->cred = NULL;
|
||||
BACKEND->session = NULL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -1652,9 +1659,10 @@ static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
|
||||
size_t buffersize, /* max amount to read */
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
ssize_t ret;
|
||||
|
||||
ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
|
||||
ret = gnutls_record_recv(BACKEND->session, buf, buffersize);
|
||||
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return -1;
|
||||
@ -1786,7 +1794,7 @@ static void *Curl_gtls_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return connssl->session;
|
||||
return BACKEND->session;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_gnutls = {
|
||||
|
@ -61,6 +61,8 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
/* apply threading? */
|
||||
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
#define THREADING_SUPPORT
|
||||
@ -214,9 +216,9 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
|
||||
return result;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
mbedtls_ver_min);
|
||||
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
mbedtls_ver_max);
|
||||
|
||||
return result;
|
||||
@ -248,9 +250,9 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
|
||||
#ifdef THREADING_SUPPORT
|
||||
entropy_init_mutex(&ts_entropy);
|
||||
mbedtls_ctr_drbg_init(&connssl->ctr_drbg);
|
||||
mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg);
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, entropy_func_mutex,
|
||||
ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, entropy_func_mutex,
|
||||
&ts_entropy, NULL, 0);
|
||||
if(ret) {
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
@ -260,11 +262,11 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
-ret, errorbuf);
|
||||
}
|
||||
#else
|
||||
mbedtls_entropy_init(&connssl->entropy);
|
||||
mbedtls_ctr_drbg_init(&connssl->ctr_drbg);
|
||||
mbedtls_entropy_init(&BACKEND->entropy);
|
||||
mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg);
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func,
|
||||
&connssl->entropy, NULL, 0);
|
||||
ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, mbedtls_entropy_func,
|
||||
&BACKEND->entropy, NULL, 0);
|
||||
if(ret) {
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
@ -275,10 +277,10 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
#endif /* THREADING_SUPPORT */
|
||||
|
||||
/* Load the trusted CA */
|
||||
mbedtls_x509_crt_init(&connssl->cacert);
|
||||
mbedtls_x509_crt_init(&BACKEND->cacert);
|
||||
|
||||
if(ssl_cafile) {
|
||||
ret = mbedtls_x509_crt_parse_file(&connssl->cacert, ssl_cafile);
|
||||
ret = mbedtls_x509_crt_parse_file(&BACKEND->cacert, ssl_cafile);
|
||||
|
||||
if(ret<0) {
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
@ -293,7 +295,7 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(ssl_capath) {
|
||||
ret = mbedtls_x509_crt_parse_path(&connssl->cacert, ssl_capath);
|
||||
ret = mbedtls_x509_crt_parse_path(&BACKEND->cacert, ssl_capath);
|
||||
|
||||
if(ret<0) {
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
@ -308,10 +310,10 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Load the client certificate */
|
||||
mbedtls_x509_crt_init(&connssl->clicert);
|
||||
mbedtls_x509_crt_init(&BACKEND->clicert);
|
||||
|
||||
if(ssl_cert) {
|
||||
ret = mbedtls_x509_crt_parse_file(&connssl->clicert, ssl_cert);
|
||||
ret = mbedtls_x509_crt_parse_file(&BACKEND->clicert, ssl_cert);
|
||||
|
||||
if(ret) {
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
@ -325,12 +327,12 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Load the client private key */
|
||||
mbedtls_pk_init(&connssl->pk);
|
||||
mbedtls_pk_init(&BACKEND->pk);
|
||||
|
||||
if(SSL_SET_OPTION(key)) {
|
||||
ret = mbedtls_pk_parse_keyfile(&connssl->pk, SSL_SET_OPTION(key),
|
||||
ret = mbedtls_pk_parse_keyfile(&BACKEND->pk, SSL_SET_OPTION(key),
|
||||
SSL_SET_OPTION(key_passwd));
|
||||
if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA))
|
||||
if(ret == 0 && !mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_RSA))
|
||||
ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
|
||||
if(ret) {
|
||||
@ -345,10 +347,10 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Load the CRL */
|
||||
mbedtls_x509_crl_init(&connssl->crl);
|
||||
mbedtls_x509_crl_init(&BACKEND->crl);
|
||||
|
||||
if(ssl_crlfile) {
|
||||
ret = mbedtls_x509_crl_parse_file(&connssl->crl, ssl_crlfile);
|
||||
ret = mbedtls_x509_crl_parse_file(&BACKEND->crl, ssl_crlfile);
|
||||
|
||||
if(ret) {
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
@ -363,14 +365,14 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
|
||||
infof(data, "mbedTLS: Connecting to %s:%d\n", hostname, port);
|
||||
|
||||
mbedtls_ssl_config_init(&connssl->config);
|
||||
mbedtls_ssl_config_init(&BACKEND->config);
|
||||
|
||||
mbedtls_ssl_init(&connssl->ssl);
|
||||
if(mbedtls_ssl_setup(&connssl->ssl, &connssl->config)) {
|
||||
mbedtls_ssl_init(&BACKEND->ssl);
|
||||
if(mbedtls_ssl_setup(&BACKEND->ssl, &BACKEND->config)) {
|
||||
failf(data, "mbedTLS: ssl_init failed");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
ret = mbedtls_ssl_config_defaults(&connssl->config,
|
||||
ret = mbedtls_ssl_config_defaults(&BACKEND->config,
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
@ -380,20 +382,20 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* new profile with RSA min key len = 1024 ... */
|
||||
mbedtls_ssl_conf_cert_profile(&connssl->config,
|
||||
mbedtls_ssl_conf_cert_profile(&BACKEND->config,
|
||||
&mbedtls_x509_crt_profile_fr);
|
||||
|
||||
switch(SSL_CONN_CONFIG(version)) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_1);
|
||||
infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n");
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_0);
|
||||
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_0);
|
||||
infof(data, "mbedTLS: Set SSL version to SSLv3\n");
|
||||
break;
|
||||
@ -412,25 +414,25 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_authmode(&connssl->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
mbedtls_ssl_conf_authmode(&BACKEND->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
|
||||
mbedtls_ssl_conf_rng(&connssl->config, mbedtls_ctr_drbg_random,
|
||||
&connssl->ctr_drbg);
|
||||
mbedtls_ssl_set_bio(&connssl->ssl, &conn->sock[sockindex],
|
||||
mbedtls_ssl_conf_rng(&BACKEND->config, mbedtls_ctr_drbg_random,
|
||||
&BACKEND->ctr_drbg);
|
||||
mbedtls_ssl_set_bio(&BACKEND->ssl, &conn->sock[sockindex],
|
||||
mbedtls_net_send,
|
||||
mbedtls_net_recv,
|
||||
NULL /* rev_timeout() */);
|
||||
|
||||
mbedtls_ssl_conf_ciphersuites(&connssl->config,
|
||||
mbedtls_ssl_conf_ciphersuites(&BACKEND->config,
|
||||
mbedtls_ssl_list_ciphersuites());
|
||||
|
||||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
|
||||
mbedtls_ssl_conf_renegotiation(&connssl->config,
|
||||
mbedtls_ssl_conf_renegotiation(&BACKEND->config,
|
||||
MBEDTLS_SSL_RENEGOTIATION_ENABLED);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
mbedtls_ssl_conf_session_tickets(&connssl->config,
|
||||
mbedtls_ssl_conf_session_tickets(&BACKEND->config,
|
||||
MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
|
||||
#endif
|
||||
|
||||
@ -440,7 +442,7 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
|
||||
ret = mbedtls_ssl_set_session(&connssl->ssl, old_session);
|
||||
ret = mbedtls_ssl_set_session(&BACKEND->ssl, old_session);
|
||||
if(ret) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret);
|
||||
@ -451,15 +453,15 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_ca_chain(&connssl->config,
|
||||
&connssl->cacert,
|
||||
&connssl->crl);
|
||||
mbedtls_ssl_conf_ca_chain(&BACKEND->config,
|
||||
&BACKEND->cacert,
|
||||
&BACKEND->crl);
|
||||
|
||||
if(SSL_SET_OPTION(key)) {
|
||||
mbedtls_ssl_conf_own_cert(&connssl->config,
|
||||
&connssl->clicert, &connssl->pk);
|
||||
mbedtls_ssl_conf_own_cert(&BACKEND->config,
|
||||
&BACKEND->clicert, &BACKEND->pk);
|
||||
}
|
||||
if(mbedtls_ssl_set_hostname(&connssl->ssl, hostname)) {
|
||||
if(mbedtls_ssl_set_hostname(&BACKEND->ssl, hostname)) {
|
||||
/* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and*
|
||||
the name to set in the SNI extension. So even if curl connects to a
|
||||
host specified as an IP address, this function must be used. */
|
||||
@ -469,7 +471,7 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
const char **p = &connssl->protocols[0];
|
||||
const char **p = &BACKEND->protocols[0];
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2)
|
||||
*p++ = NGHTTP2_PROTO_VERSION_ID;
|
||||
@ -478,19 +480,19 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
*p = NULL;
|
||||
/* this function doesn't clone the protocols array, which is why we need
|
||||
to keep it around */
|
||||
if(mbedtls_ssl_conf_alpn_protocols(&connssl->config,
|
||||
&connssl->protocols[0])) {
|
||||
if(mbedtls_ssl_conf_alpn_protocols(&BACKEND->config,
|
||||
&BACKEND->protocols[0])) {
|
||||
failf(data, "Failed setting ALPN protocols");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
for(p = &connssl->protocols[0]; *p; ++p)
|
||||
for(p = &BACKEND->protocols[0]; *p; ++p)
|
||||
infof(data, "ALPN, offering %s\n", *p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MBEDTLS_DEBUG
|
||||
/* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
|
||||
mbedtls_ssl_conf_dbg(&connssl->config, mbed_debug, data);
|
||||
mbedtls_ssl_conf_dbg(&BACKEND->config, mbed_debug, data);
|
||||
/* - 0 No debug
|
||||
* - 1 Error
|
||||
* - 2 State change
|
||||
@ -502,7 +504,7 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
|
||||
/* give application a chance to interfere with mbedTLS set up. */
|
||||
if(data->set.ssl.fsslctx) {
|
||||
ret = (*data->set.ssl.fsslctx)(data, &connssl->config,
|
||||
ret = (*data->set.ssl.fsslctx)(data, &BACKEND->config,
|
||||
data->set.ssl.fsslctxp);
|
||||
if(ret) {
|
||||
failf(data, "error signaled by ssl ctx callback");
|
||||
@ -537,7 +539,7 @@ mbed_connect_step2(struct connectdata *conn,
|
||||
conn->recv[sockindex] = mbed_recv;
|
||||
conn->send[sockindex] = mbed_send;
|
||||
|
||||
ret = mbedtls_ssl_handshake(&connssl->ssl);
|
||||
ret = mbedtls_ssl_handshake(&BACKEND->ssl);
|
||||
|
||||
if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
connssl->connecting_state = ssl_connect_2_reading;
|
||||
@ -557,10 +559,10 @@ mbed_connect_step2(struct connectdata *conn,
|
||||
}
|
||||
|
||||
infof(data, "mbedTLS: Handshake complete, cipher is %s\n",
|
||||
mbedtls_ssl_get_ciphersuite(&conn->ssl[sockindex].ssl)
|
||||
mbedtls_ssl_get_ciphersuite(&BACKEND->ssl)
|
||||
);
|
||||
|
||||
ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl);
|
||||
ret = mbedtls_ssl_get_verify_result(&BACKEND->ssl);
|
||||
|
||||
if(ret && SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
|
||||
@ -580,7 +582,7 @@ mbed_connect_step2(struct connectdata *conn,
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
|
||||
peercert = mbedtls_ssl_get_peer_cert(&connssl->ssl);
|
||||
peercert = mbedtls_ssl_get_peer_cert(&BACKEND->ssl);
|
||||
|
||||
if(peercert && data->set.verbose) {
|
||||
const size_t bufsize = 16384;
|
||||
@ -650,7 +652,7 @@ mbed_connect_step2(struct connectdata *conn,
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
next_protocol = mbedtls_ssl_get_alpn_protocol(&connssl->ssl);
|
||||
next_protocol = mbedtls_ssl_get_alpn_protocol(&BACKEND->ssl);
|
||||
|
||||
if(next_protocol) {
|
||||
infof(data, "ALPN, server accepted to use %s\n", next_protocol);
|
||||
@ -700,7 +702,7 @@ mbed_connect_step3(struct connectdata *conn,
|
||||
|
||||
mbedtls_ssl_session_init(our_ssl_sessionid);
|
||||
|
||||
ret = mbedtls_ssl_get_session(&connssl->ssl, our_ssl_sessionid);
|
||||
ret = mbedtls_ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
|
||||
if(ret) {
|
||||
free(our_ssl_sessionid);
|
||||
failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
|
||||
@ -730,9 +732,10 @@ static ssize_t mbed_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
int ret = -1;
|
||||
|
||||
ret = mbedtls_ssl_write(&conn->ssl[sockindex].ssl,
|
||||
ret = mbedtls_ssl_write(&BACKEND->ssl,
|
||||
(unsigned char *)mem, len);
|
||||
|
||||
if(ret < 0) {
|
||||
@ -751,15 +754,16 @@ static void Curl_mbedtls_close_all(struct Curl_easy *data)
|
||||
|
||||
static void Curl_mbedtls_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
mbedtls_pk_free(&conn->ssl[sockindex].pk);
|
||||
mbedtls_x509_crt_free(&conn->ssl[sockindex].clicert);
|
||||
mbedtls_x509_crt_free(&conn->ssl[sockindex].cacert);
|
||||
mbedtls_x509_crl_free(&conn->ssl[sockindex].crl);
|
||||
mbedtls_ssl_config_free(&conn->ssl[sockindex].config);
|
||||
mbedtls_ssl_free(&conn->ssl[sockindex].ssl);
|
||||
mbedtls_ctr_drbg_free(&conn->ssl[sockindex].ctr_drbg);
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
mbedtls_pk_free(&BACKEND->pk);
|
||||
mbedtls_x509_crt_free(&BACKEND->clicert);
|
||||
mbedtls_x509_crt_free(&BACKEND->cacert);
|
||||
mbedtls_x509_crl_free(&BACKEND->crl);
|
||||
mbedtls_ssl_config_free(&BACKEND->config);
|
||||
mbedtls_ssl_free(&BACKEND->ssl);
|
||||
mbedtls_ctr_drbg_free(&BACKEND->ctr_drbg);
|
||||
#ifndef THREADING_SUPPORT
|
||||
mbedtls_entropy_free(&conn->ssl[sockindex].entropy);
|
||||
mbedtls_entropy_free(&BACKEND->entropy);
|
||||
#endif /* THREADING_SUPPORT */
|
||||
}
|
||||
|
||||
@ -767,11 +771,12 @@ static ssize_t mbed_recv(struct connectdata *conn, int num,
|
||||
char *buf, size_t buffersize,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
int ret = -1;
|
||||
ssize_t len = -1;
|
||||
|
||||
memset(buf, 0, buffersize);
|
||||
ret = mbedtls_ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf,
|
||||
ret = mbedtls_ssl_read(&BACKEND->ssl, (unsigned char *)buf,
|
||||
buffersize);
|
||||
|
||||
if(ret <= 0) {
|
||||
@ -1001,7 +1006,8 @@ static void Curl_mbedtls_cleanup(void)
|
||||
static bool Curl_mbedtls_data_pending(const struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
return mbedtls_ssl_get_bytes_avail(&conn->ssl[sockindex].ssl) != 0;
|
||||
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
return mbedtls_ssl_get_bytes_avail(&BACKEND->ssl) != 0;
|
||||
}
|
||||
|
||||
static void Curl_mbedtls_sha256sum(const unsigned char *input,
|
||||
@ -1016,7 +1022,7 @@ static void *Curl_mbedtls_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return &connssl->ssl;
|
||||
return &BACKEND->ssl;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_mbedtls = {
|
||||
|
106
lib/vtls/nss.c
106
lib/vtls/nss.c
@ -78,6 +78,8 @@
|
||||
/* enough to fit the string "PEM Token #[0|1]" */
|
||||
#define SLOTSIZE 13
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
static PRLock *nss_initlock = NULL;
|
||||
static PRLock *nss_crllock = NULL;
|
||||
static PRLock *nss_findslot_lock = NULL;
|
||||
@ -396,7 +398,7 @@ static CURLcode insert_wrapped_ptr(struct curl_llist *list, void *ptr)
|
||||
/* Call PK11_CreateGenericObject() with the given obj_class and filename. If
|
||||
* the call succeeds, append the object handle to the list of objects so that
|
||||
* the object can be destroyed in Curl_nss_close(). */
|
||||
static CURLcode nss_create_object(struct ssl_connect_data *ssl,
|
||||
static CURLcode nss_create_object(struct ssl_connect_data *connssl,
|
||||
CK_OBJECT_CLASS obj_class,
|
||||
const char *filename, bool cacert)
|
||||
{
|
||||
@ -435,14 +437,14 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
|
||||
if(!obj)
|
||||
return result;
|
||||
|
||||
if(insert_wrapped_ptr(&ssl->obj_list, obj) != CURLE_OK) {
|
||||
if(insert_wrapped_ptr(&BACKEND->obj_list, obj) != CURLE_OK) {
|
||||
PK11_DestroyGenericObject(obj);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!cacert && CKO_CERTIFICATE == obj_class)
|
||||
/* store reference to a client certificate */
|
||||
ssl->obj_clicert = obj;
|
||||
BACKEND->obj_clicert = obj;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@ -1017,7 +1019,7 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
|
||||
const char *pinnedpubkey)
|
||||
{
|
||||
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||
struct Curl_easy *data = connssl->data;
|
||||
struct Curl_easy *data = BACKEND->data;
|
||||
CERTCertificate *cert;
|
||||
|
||||
if(!pinnedpubkey)
|
||||
@ -1025,7 +1027,7 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
|
||||
return CURLE_OK;
|
||||
|
||||
/* get peer certificate */
|
||||
cert = SSL_PeerCertificate(connssl->handle);
|
||||
cert = SSL_PeerCertificate(BACKEND->handle);
|
||||
if(cert) {
|
||||
/* extract public key from peer certificate */
|
||||
SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
|
||||
@ -1069,11 +1071,11 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
||||
struct SECKEYPrivateKeyStr **pRetKey)
|
||||
{
|
||||
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
|
||||
struct Curl_easy *data = connssl->data;
|
||||
const char *nickname = connssl->client_nickname;
|
||||
struct Curl_easy *data = BACKEND->data;
|
||||
const char *nickname = BACKEND->client_nickname;
|
||||
static const char pem_slotname[] = "PEM Token #1";
|
||||
|
||||
if(connssl->obj_clicert) {
|
||||
if(BACKEND->obj_clicert) {
|
||||
/* use the cert/key provided by PEM reader */
|
||||
SECItem cert_der = { 0, NULL, 0 };
|
||||
void *proto_win = SSL_RevealPinArg(sock);
|
||||
@ -1086,7 +1088,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if(PK11_ReadRawAttribute(PK11_TypeGeneric, connssl->obj_clicert, CKA_VALUE,
|
||||
if(PK11_ReadRawAttribute(PK11_TypeGeneric, BACKEND->obj_clicert, CKA_VALUE,
|
||||
&cert_der) != SECSuccess) {
|
||||
failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
|
||||
PK11_FreeSlot(slot);
|
||||
@ -1428,11 +1430,12 @@ static void Curl_nss_cleanup(void)
|
||||
*/
|
||||
static int Curl_nss_check_cxn(struct connectdata *conn)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
||||
int rc;
|
||||
char buf;
|
||||
|
||||
rc =
|
||||
PR_Recv(conn->ssl[FIRSTSOCKET].handle, (void *)&buf, 1, PR_MSG_PEEK,
|
||||
PR_Recv(BACKEND->handle, (void *)&buf, 1, PR_MSG_PEEK,
|
||||
PR_SecondsToInterval(1));
|
||||
if(rc > 0)
|
||||
return 1; /* connection still in place */
|
||||
@ -1446,26 +1449,26 @@ static int Curl_nss_check_cxn(struct connectdata *conn)
|
||||
static void nss_close(struct ssl_connect_data *connssl)
|
||||
{
|
||||
/* before the cleanup, check whether we are using a client certificate */
|
||||
const bool client_cert = (connssl->client_nickname != NULL)
|
||||
|| (connssl->obj_clicert != NULL);
|
||||
const bool client_cert = (BACKEND->client_nickname != NULL)
|
||||
|| (BACKEND->obj_clicert != NULL);
|
||||
|
||||
free(connssl->client_nickname);
|
||||
connssl->client_nickname = NULL;
|
||||
free(BACKEND->client_nickname);
|
||||
BACKEND->client_nickname = NULL;
|
||||
|
||||
/* destroy all NSS objects in order to avoid failure of NSS shutdown */
|
||||
Curl_llist_destroy(&connssl->obj_list, NULL);
|
||||
connssl->obj_clicert = NULL;
|
||||
Curl_llist_destroy(&BACKEND->obj_list, NULL);
|
||||
BACKEND->obj_clicert = NULL;
|
||||
|
||||
if(connssl->handle) {
|
||||
if(BACKEND->handle) {
|
||||
if(client_cert)
|
||||
/* A server might require different authentication based on the
|
||||
* particular path being requested by the client. To support this
|
||||
* scenario, we must ensure that a connection will never reuse the
|
||||
* authentication data from a previous connection. */
|
||||
SSL_InvalidateSession(connssl->handle);
|
||||
SSL_InvalidateSession(BACKEND->handle);
|
||||
|
||||
PR_Close(connssl->handle);
|
||||
connssl->handle = NULL;
|
||||
PR_Close(BACKEND->handle);
|
||||
BACKEND->handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1477,16 +1480,17 @@ static void Curl_nss_close(struct connectdata *conn, int sockindex)
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
|
||||
|
||||
if(connssl->handle || connssl_proxy->handle) {
|
||||
if(BACKEND->handle || connssl_proxy->handle) {
|
||||
/* NSS closes the socket we previously handed to it, so we must mark it
|
||||
as closed to avoid double close */
|
||||
fake_sclose(conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
if(connssl->handle)
|
||||
/* nss_close(connssl) will transitively close also connssl_proxy->handle
|
||||
if both are used. Clear it to avoid a double close leading to crash. */
|
||||
if(BACKEND->handle)
|
||||
/* nss_close(connssl) will transitively close also
|
||||
connssl_proxy->handle if both are used. Clear it to avoid
|
||||
a double close leading to crash. */
|
||||
connssl_proxy->handle = NULL;
|
||||
|
||||
nss_close(connssl);
|
||||
@ -1731,7 +1735,7 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
|
||||
}
|
||||
|
||||
/* cleanup on connection failure */
|
||||
Curl_llist_destroy(&connssl->obj_list, NULL);
|
||||
Curl_llist_destroy(&BACKEND->obj_list, NULL);
|
||||
|
||||
return curlerr;
|
||||
}
|
||||
@ -1745,7 +1749,7 @@ static CURLcode nss_set_blocking(struct ssl_connect_data *connssl,
|
||||
sock_opt.option = PR_SockOpt_Nonblocking;
|
||||
sock_opt.value.non_blocking = !blocking;
|
||||
|
||||
if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS)
|
||||
if(PR_SetSocketOption(BACKEND->handle, &sock_opt) != PR_SUCCESS)
|
||||
return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
|
||||
|
||||
return CURLE_OK;
|
||||
@ -1769,10 +1773,10 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
SSL_LIBRARY_VERSION_TLS_1_0 /* max */
|
||||
};
|
||||
|
||||
connssl->data = data;
|
||||
BACKEND->data = data;
|
||||
|
||||
/* list of all NSS objects we need to destroy in Curl_nss_close() */
|
||||
Curl_llist_init(&connssl->obj_list, nss_destroy_object);
|
||||
Curl_llist_init(&BACKEND->obj_list, nss_destroy_object);
|
||||
|
||||
/* FIXME. NSS doesn't support multiple databases open at the same time. */
|
||||
PR_Lock(nss_initlock);
|
||||
@ -1881,7 +1885,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
|
||||
if(nickname) {
|
||||
/* we are not going to use libnsspem.so to read the client cert */
|
||||
connssl->obj_clicert = NULL;
|
||||
BACKEND->obj_clicert = NULL;
|
||||
}
|
||||
else {
|
||||
CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
|
||||
@ -1894,10 +1898,10 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* store the nickname for SelectClientCert() called during handshake */
|
||||
connssl->client_nickname = nickname;
|
||||
BACKEND->client_nickname = nickname;
|
||||
}
|
||||
else
|
||||
connssl->client_nickname = NULL;
|
||||
BACKEND->client_nickname = NULL;
|
||||
|
||||
if(SSL_GetClientAuthDataHook(model, SelectClientCert,
|
||||
(void *)connssl) != SECSuccess) {
|
||||
@ -1938,8 +1942,8 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* import our model socket onto the current I/O stack */
|
||||
connssl->handle = SSL_ImportFD(model, nspr_io);
|
||||
if(!connssl->handle) {
|
||||
BACKEND->handle = SSL_ImportFD(model, nspr_io);
|
||||
if(!BACKEND->handle) {
|
||||
if(!second_layer)
|
||||
PR_Close(nspr_io);
|
||||
goto error;
|
||||
@ -1950,36 +1954,36 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* This is the password associated with the cert that we're using */
|
||||
if(SSL_SET_OPTION(key_passwd)) {
|
||||
SSL_SetPKCS11PinArg(connssl->handle, SSL_SET_OPTION(key_passwd));
|
||||
SSL_SetPKCS11PinArg(BACKEND->handle, SSL_SET_OPTION(key_passwd));
|
||||
}
|
||||
|
||||
#ifdef SSL_ENABLE_OCSP_STAPLING
|
||||
if(SSL_CONN_CONFIG(verifystatus)) {
|
||||
if(SSL_OptionSet(connssl->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
|
||||
if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
|
||||
!= SECSuccess)
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_ENABLE_NPN
|
||||
if(SSL_OptionSet(connssl->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
|
||||
if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
|
||||
? PR_TRUE : PR_FALSE) != SECSuccess)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
#ifdef SSL_ENABLE_ALPN
|
||||
if(SSL_OptionSet(connssl->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
|
||||
if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
|
||||
? PR_TRUE : PR_FALSE) != SECSuccess)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
|
||||
if(data->set.ssl.falsestart) {
|
||||
if(SSL_OptionSet(connssl->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
|
||||
if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
|
||||
!= SECSuccess)
|
||||
goto error;
|
||||
|
||||
if(SSL_SetCanFalseStartCallback(connssl->handle, CanFalseStartCallback,
|
||||
if(SSL_SetCanFalseStartCallback(BACKEND->handle, CanFalseStartCallback,
|
||||
conn) != SECSuccess)
|
||||
goto error;
|
||||
}
|
||||
@ -2003,24 +2007,24 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
|
||||
cur += ALPN_HTTP_1_1_LENGTH;
|
||||
|
||||
if(SSL_SetNextProtoNego(connssl->handle, protocols, cur) != SECSuccess)
|
||||
if(SSL_SetNextProtoNego(BACKEND->handle, protocols, cur) != SECSuccess)
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Force handshake on next I/O */
|
||||
if(SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE)
|
||||
if(SSL_ResetHandshake(BACKEND->handle, /* asServer */ PR_FALSE)
|
||||
!= SECSuccess)
|
||||
goto error;
|
||||
|
||||
/* propagate hostname to the TLS layer */
|
||||
if(SSL_SetURL(connssl->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
if(SSL_SetURL(BACKEND->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
/* prevent NSS from re-using the session for a different hostname */
|
||||
if(SSL_SetSockPeerID(connssl->handle, SSL_IS_PROXY() ?
|
||||
if(SSL_SetSockPeerID(BACKEND->handle, SSL_IS_PROXY() ?
|
||||
conn->http_proxy.host.name : conn->host.name)
|
||||
!= SECSuccess)
|
||||
goto error;
|
||||
@ -2057,7 +2061,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* Force the handshake now */
|
||||
timeout = PR_MillisecondsToInterval((PRUint32) time_left);
|
||||
if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
|
||||
if(SSL_ForceHandshakeWithTimeout(BACKEND->handle, timeout) != SECSuccess) {
|
||||
if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
|
||||
/* blocking direction is updated by nss_update_connecting_state() */
|
||||
return CURLE_AGAIN;
|
||||
@ -2068,7 +2072,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
||||
goto error;
|
||||
}
|
||||
|
||||
result = display_conn_info(conn, connssl->handle);
|
||||
result = display_conn_info(conn, BACKEND->handle);
|
||||
if(result)
|
||||
goto error;
|
||||
|
||||
@ -2077,7 +2081,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
||||
char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert));
|
||||
if(nickname) {
|
||||
/* we support only nicknames in case of issuercert for now */
|
||||
ret = check_issuer_cert(connssl->handle, nickname);
|
||||
ret = check_issuer_cert(BACKEND->handle, nickname);
|
||||
free(nickname);
|
||||
}
|
||||
|
||||
@ -2185,9 +2189,9 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */
|
||||
|
||||
/* The SelectClientCert() hook uses this for infof() and failf() but the
|
||||
handle stored in nss_setup_connect() could have already been freed. */
|
||||
connssl->data = conn->data;
|
||||
BACKEND->data = conn->data;
|
||||
|
||||
rc = PR_Send(connssl->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
|
||||
rc = PR_Send(BACKEND->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
|
||||
if(rc < 0) {
|
||||
PRInt32 err = PR_GetError();
|
||||
if(err == PR_WOULD_BLOCK_ERROR)
|
||||
@ -2222,9 +2226,9 @@ static ssize_t nss_recv(struct connectdata *conn, /* connection data */
|
||||
|
||||
/* The SelectClientCert() hook uses this for infof() and failf() but the
|
||||
handle stored in nss_setup_connect() could have already been freed. */
|
||||
connssl->data = conn->data;
|
||||
BACKEND->data = conn->data;
|
||||
|
||||
nread = PR_Recv(connssl->handle, buf, (int)buffersize, 0,
|
||||
nread = PR_Recv(BACKEND->handle, buf, (int)buffersize, 0,
|
||||
PR_INTERVAL_NO_WAIT);
|
||||
if(nread < 0) {
|
||||
/* failed SSL read */
|
||||
@ -2327,7 +2331,7 @@ static void *Curl_nss_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return connssl->handle;
|
||||
return BACKEND->handle;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_nss = {
|
||||
|
@ -155,6 +155,8 @@ static unsigned long OpenSSL_version_num(void)
|
||||
#define DEFAULT_CIPHER_SELECTION \
|
||||
"ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
/*
|
||||
* Number of bytes to read from the random number seed file. This must be
|
||||
* a finite value (because some entropy "files" like /dev/urandom have
|
||||
@ -956,16 +958,16 @@ static struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data)
|
||||
|
||||
static void ossl_close(struct ssl_connect_data *connssl)
|
||||
{
|
||||
if(connssl->handle) {
|
||||
(void)SSL_shutdown(connssl->handle);
|
||||
SSL_set_connect_state(connssl->handle);
|
||||
if(BACKEND->handle) {
|
||||
(void)SSL_shutdown(BACKEND->handle);
|
||||
SSL_set_connect_state(BACKEND->handle);
|
||||
|
||||
SSL_free(connssl->handle);
|
||||
connssl->handle = NULL;
|
||||
SSL_free(BACKEND->handle);
|
||||
BACKEND->handle = NULL;
|
||||
}
|
||||
if(connssl->ctx) {
|
||||
SSL_CTX_free(connssl->ctx);
|
||||
connssl->ctx = NULL;
|
||||
if(BACKEND->ctx) {
|
||||
SSL_CTX_free(BACKEND->ctx);
|
||||
BACKEND->ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1001,9 +1003,9 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
|
||||
we do not send one. Let's hope other servers do the same... */
|
||||
|
||||
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
|
||||
(void)SSL_shutdown(connssl->handle);
|
||||
(void)SSL_shutdown(BACKEND->handle);
|
||||
|
||||
if(connssl->handle) {
|
||||
if(BACKEND->handle) {
|
||||
buffsize = (int)sizeof(buf);
|
||||
while(!done) {
|
||||
int what = SOCKET_READABLE(conn->sock[sockindex],
|
||||
@ -1013,9 +1015,8 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* Something to read, let's do it and hope that it is the close
|
||||
notify alert from the server */
|
||||
nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf,
|
||||
buffsize);
|
||||
err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread);
|
||||
nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize);
|
||||
err = SSL_get_error(BACKEND->handle, (int)nread);
|
||||
|
||||
switch(err) {
|
||||
case SSL_ERROR_NONE: /* this is not an error */
|
||||
@ -1060,7 +1061,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
|
||||
|
||||
if(data->set.verbose) {
|
||||
#ifdef HAVE_SSL_GET_SHUTDOWN
|
||||
switch(SSL_get_shutdown(connssl->handle)) {
|
||||
switch(SSL_get_shutdown(BACKEND->handle)) {
|
||||
case SSL_SENT_SHUTDOWN:
|
||||
infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
|
||||
break;
|
||||
@ -1075,8 +1076,8 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
|
||||
#endif
|
||||
}
|
||||
|
||||
SSL_free(connssl->handle);
|
||||
connssl->handle = NULL;
|
||||
SSL_free(BACKEND->handle);
|
||||
BACKEND->handle = NULL;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@ -1350,7 +1351,7 @@ static CURLcode verifystatus(struct connectdata *conn,
|
||||
X509_STORE *st = NULL;
|
||||
STACK_OF(X509) *ch = NULL;
|
||||
|
||||
long len = SSL_get_tlsext_status_ocsp_resp(connssl->handle, &p);
|
||||
long len = SSL_get_tlsext_status_ocsp_resp(BACKEND->handle, &p);
|
||||
|
||||
if(!p) {
|
||||
failf(data, "No OCSP response received");
|
||||
@ -1380,8 +1381,8 @@ static CURLcode verifystatus(struct connectdata *conn,
|
||||
goto end;
|
||||
}
|
||||
|
||||
ch = SSL_get_peer_cert_chain(connssl->handle);
|
||||
st = SSL_CTX_get_cert_store(connssl->ctx);
|
||||
ch = SSL_get_peer_cert_chain(BACKEND->handle);
|
||||
st = SSL_CTX_get_cert_store(BACKEND->ctx);
|
||||
|
||||
#if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
@ -1772,7 +1773,7 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
|
||||
#ifdef TLS1_3_VERSION
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
SSL_CTX_set_max_proto_version(connssl->ctx, TLS1_3_VERSION);
|
||||
SSL_CTX_set_max_proto_version(BACKEND->ctx, TLS1_3_VERSION);
|
||||
*ctx_options |= SSL_OP_NO_TLSv1_2;
|
||||
}
|
||||
#else
|
||||
@ -1923,25 +1924,25 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
if(connssl->ctx)
|
||||
SSL_CTX_free(connssl->ctx);
|
||||
connssl->ctx = SSL_CTX_new(req_method);
|
||||
if(BACKEND->ctx)
|
||||
SSL_CTX_free(BACKEND->ctx);
|
||||
BACKEND->ctx = SSL_CTX_new(req_method);
|
||||
|
||||
if(!connssl->ctx) {
|
||||
if(!BACKEND->ctx) {
|
||||
failf(data, "SSL: couldn't create a context: %s",
|
||||
ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer)));
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef SSL_MODE_RELEASE_BUFFERS
|
||||
SSL_CTX_set_mode(connssl->ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||
SSL_CTX_set_mode(BACKEND->ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||
#endif
|
||||
|
||||
#ifdef SSL_CTRL_SET_MSG_CALLBACK
|
||||
if(data->set.fdebug && data->set.verbose) {
|
||||
/* the SSL trace callback is only used for verbose logging */
|
||||
SSL_CTX_set_msg_callback(connssl->ctx, ssl_tls_trace);
|
||||
SSL_CTX_set_msg_callback_arg(connssl->ctx, conn);
|
||||
SSL_CTX_set_msg_callback(BACKEND->ctx, ssl_tls_trace);
|
||||
SSL_CTX_set_msg_callback_arg(BACKEND->ctx, conn);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2058,11 +2059,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
SSL_CTX_set_options(connssl->ctx, ctx_options);
|
||||
SSL_CTX_set_options(BACKEND->ctx, ctx_options);
|
||||
|
||||
#ifdef HAS_NPN
|
||||
if(conn->bits.tls_enable_npn)
|
||||
SSL_CTX_set_next_proto_select_cb(connssl->ctx, select_next_proto_cb, conn);
|
||||
SSL_CTX_set_next_proto_select_cb(BACKEND->ctx, select_next_proto_cb, conn);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
@ -2090,12 +2091,12 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
/* expects length prefixed preference ordered list of protocols in wire
|
||||
* format
|
||||
*/
|
||||
SSL_CTX_set_alpn_protos(connssl->ctx, protocols, cur);
|
||||
SSL_CTX_set_alpn_protos(BACKEND->ctx, protocols, cur);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ssl_cert || ssl_cert_type) {
|
||||
if(!cert_stuff(conn, connssl->ctx, ssl_cert, ssl_cert_type,
|
||||
if(!cert_stuff(conn, BACKEND->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() */
|
||||
@ -2106,7 +2107,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
ciphers = SSL_CONN_CONFIG(cipher_list);
|
||||
if(!ciphers)
|
||||
ciphers = (char *)DEFAULT_CIPHER_SELECTION;
|
||||
if(!SSL_CTX_set_cipher_list(connssl->ctx, ciphers)) {
|
||||
if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
|
||||
failf(data, "failed setting cipher list: %s", ciphers);
|
||||
return CURLE_SSL_CIPHER;
|
||||
}
|
||||
@ -2118,18 +2119,18 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
|
||||
infof(data, "Using TLS-SRP username: %s\n", ssl_username);
|
||||
|
||||
if(!SSL_CTX_set_srp_username(connssl->ctx, ssl_username)) {
|
||||
if(!SSL_CTX_set_srp_username(BACKEND->ctx, ssl_username)) {
|
||||
failf(data, "Unable to set SRP user name");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
if(!SSL_CTX_set_srp_password(connssl->ctx, SSL_SET_OPTION(password))) {
|
||||
if(!SSL_CTX_set_srp_password(BACKEND->ctx, SSL_SET_OPTION(password))) {
|
||||
failf(data, "failed setting SRP password");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
if(!SSL_CONN_CONFIG(cipher_list)) {
|
||||
infof(data, "Setting cipher list SRP\n");
|
||||
|
||||
if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) {
|
||||
if(!SSL_CTX_set_cipher_list(BACKEND->ctx, "SRP")) {
|
||||
failf(data, "failed setting SRP cipher list");
|
||||
return CURLE_SSL_CIPHER;
|
||||
}
|
||||
@ -2140,7 +2141,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
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, ssl_cafile, ssl_capath)) {
|
||||
if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) {
|
||||
if(verifypeer) {
|
||||
/* Fail if we insist on successfully verifying the server. */
|
||||
failf(data, "error setting certificate verify locations:\n"
|
||||
@ -2168,14 +2169,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
else if(verifypeer) {
|
||||
/* verfying the peer without any CA certificates won't
|
||||
work so use openssl's built in default as fallback */
|
||||
SSL_CTX_set_default_verify_paths(connssl->ctx);
|
||||
SSL_CTX_set_default_verify_paths(BACKEND->ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
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),
|
||||
lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(BACKEND->ctx),
|
||||
X509_LOOKUP_file());
|
||||
if(!lookup ||
|
||||
(!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) {
|
||||
@ -2184,7 +2185,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
/* Everything is fine. */
|
||||
infof(data, "successfully load CRL file:\n");
|
||||
X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
|
||||
X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
|
||||
X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
|
||||
|
||||
infof(data, " CRLfile: %s\n", ssl_crlfile);
|
||||
@ -2199,7 +2200,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
*/
|
||||
#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
|
||||
if(verifypeer) {
|
||||
X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
|
||||
X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
|
||||
X509_V_FLAG_TRUSTED_FIRST);
|
||||
}
|
||||
#endif
|
||||
@ -2208,12 +2209,12 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
* fail to connect if the verification fails, or if it should continue
|
||||
* anyway. In the latter case the result of the verification is checked with
|
||||
* SSL_get_verify_result() below. */
|
||||
SSL_CTX_set_verify(connssl->ctx,
|
||||
SSL_CTX_set_verify(BACKEND->ctx,
|
||||
verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
|
||||
|
||||
/* give application a chance to interfere with SSL set up. */
|
||||
if(data->set.ssl.fsslctx) {
|
||||
result = (*data->set.ssl.fsslctx)(data, connssl->ctx,
|
||||
result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
|
||||
data->set.ssl.fsslctxp);
|
||||
if(result) {
|
||||
failf(data, "error signaled by ssl ctx callback");
|
||||
@ -2222,10 +2223,10 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* Lets make an SSL structure */
|
||||
if(connssl->handle)
|
||||
SSL_free(connssl->handle);
|
||||
connssl->handle = SSL_new(connssl->ctx);
|
||||
if(!connssl->handle) {
|
||||
if(BACKEND->handle)
|
||||
SSL_free(BACKEND->handle);
|
||||
BACKEND->handle = SSL_new(BACKEND->ctx);
|
||||
if(!BACKEND->handle) {
|
||||
failf(data, "SSL: couldn't create a context (handle)!");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -2233,19 +2234,19 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
|
||||
!defined(OPENSSL_NO_OCSP)
|
||||
if(SSL_CONN_CONFIG(verifystatus))
|
||||
SSL_set_tlsext_status_type(connssl->handle, TLSEXT_STATUSTYPE_ocsp);
|
||||
SSL_set_tlsext_status_type(BACKEND->handle, TLSEXT_STATUSTYPE_ocsp);
|
||||
#endif
|
||||
|
||||
SSL_set_connect_state(connssl->handle);
|
||||
SSL_set_connect_state(BACKEND->handle);
|
||||
|
||||
connssl->server_cert = 0x0;
|
||||
BACKEND->server_cert = 0x0;
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||
if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
|
||||
#ifdef ENABLE_IPV6
|
||||
(0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
|
||||
#endif
|
||||
sni &&
|
||||
!SSL_set_tlsext_host_name(connssl->handle, hostname))
|
||||
!SSL_set_tlsext_host_name(BACKEND->handle, hostname))
|
||||
infof(data, "WARNING: failed to configure server name indication (SNI) "
|
||||
"TLS extension\n");
|
||||
#endif
|
||||
@ -2257,7 +2258,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
|
||||
/* we got a session id, use it! */
|
||||
if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
|
||||
if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
failf(data, "SSL: SSL_set_session failed: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer,
|
||||
@ -2272,13 +2273,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
|
||||
if(conn->proxy_ssl[sockindex].use) {
|
||||
BIO *const bio = BIO_new(BIO_f_ssl());
|
||||
SSL *handle = conn->proxy_ssl[sockindex].handle;
|
||||
DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
|
||||
DEBUGASSERT(conn->proxy_ssl[sockindex].handle != NULL);
|
||||
DEBUGASSERT(BACKEND->handle != NULL);
|
||||
DEBUGASSERT(bio != NULL);
|
||||
BIO_set_ssl(bio, conn->proxy_ssl[sockindex].handle, FALSE);
|
||||
SSL_set_bio(connssl->handle, bio, bio);
|
||||
BIO_set_ssl(bio, handle, FALSE);
|
||||
SSL_set_bio(handle, bio, bio);
|
||||
}
|
||||
else if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
|
||||
else if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) {
|
||||
/* pass the raw socket into the SSL layers */
|
||||
failf(data, "SSL: SSL_set_fd failed: %s",
|
||||
ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)));
|
||||
@ -2303,13 +2305,13 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
err = SSL_connect(connssl->handle);
|
||||
err = SSL_connect(BACKEND->handle);
|
||||
|
||||
/* 1 is fine
|
||||
0 is "not successful but was shut down controlled"
|
||||
<0 is "handshake was not successful, because a fatal error occurred" */
|
||||
if(1 != err) {
|
||||
int detail = SSL_get_error(connssl->handle, err);
|
||||
int detail = SSL_get_error(BACKEND->handle, err);
|
||||
|
||||
if(SSL_ERROR_WANT_READ == detail) {
|
||||
connssl->connecting_state = ssl_connect_2_reading;
|
||||
@ -2343,7 +2345,7 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
(reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
|
||||
result = CURLE_SSL_CACERT;
|
||||
|
||||
lerr = SSL_get_verify_result(connssl->handle);
|
||||
lerr = SSL_get_verify_result(BACKEND->handle);
|
||||
if(lerr != X509_V_OK) {
|
||||
*certverifyresult = lerr;
|
||||
snprintf(error_buffer, sizeof(error_buffer),
|
||||
@ -2387,8 +2389,8 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* Informational message */
|
||||
infof(data, "SSL connection using %s / %s\n",
|
||||
get_ssl_version_txt(connssl->handle),
|
||||
SSL_get_cipher(connssl->handle));
|
||||
get_ssl_version_txt(BACKEND->handle),
|
||||
SSL_get_cipher(BACKEND->handle));
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
/* Sets data and len to negotiated protocol, len is 0 if no protocol was
|
||||
@ -2397,7 +2399,7 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
const unsigned char *neg_protocol;
|
||||
unsigned int len;
|
||||
SSL_get0_alpn_selected(connssl->handle, &neg_protocol, &len);
|
||||
SSL_get0_alpn_selected(BACKEND->handle, &neg_protocol, &len);
|
||||
if(len != 0) {
|
||||
infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol);
|
||||
|
||||
@ -2543,7 +2545,7 @@ static CURLcode get_cert_chain(struct connectdata *conn,
|
||||
int numcerts;
|
||||
BIO *mem;
|
||||
|
||||
sk = SSL_get_peer_cert_chain(connssl->handle);
|
||||
sk = SSL_get_peer_cert_chain(BACKEND->handle);
|
||||
if(!sk) {
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -2833,8 +2835,8 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
/* we've been asked to gather certificate info! */
|
||||
(void)get_cert_chain(conn, connssl);
|
||||
|
||||
connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
|
||||
if(!connssl->server_cert) {
|
||||
BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle);
|
||||
if(!BACKEND->server_cert) {
|
||||
BIO_free(mem);
|
||||
if(!strict)
|
||||
return CURLE_OK;
|
||||
@ -2845,16 +2847,16 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
|
||||
infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server");
|
||||
|
||||
rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
|
||||
rc = x509_name_oneline(X509_get_subject_name(BACKEND->server_cert),
|
||||
buffer, sizeof(buffer));
|
||||
infof(data, " subject: %s\n", rc?"[NONE]":buffer);
|
||||
|
||||
ASN1_TIME_print(mem, X509_get0_notBefore(connssl->server_cert));
|
||||
ASN1_TIME_print(mem, X509_get0_notBefore(BACKEND->server_cert));
|
||||
len = BIO_get_mem_data(mem, (char **) &ptr);
|
||||
infof(data, " start date: %.*s\n", len, ptr);
|
||||
rc = BIO_reset(mem);
|
||||
|
||||
ASN1_TIME_print(mem, X509_get0_notAfter(connssl->server_cert));
|
||||
ASN1_TIME_print(mem, X509_get0_notAfter(BACKEND->server_cert));
|
||||
len = BIO_get_mem_data(mem, (char **) &ptr);
|
||||
infof(data, " expire date: %.*s\n", len, ptr);
|
||||
rc = BIO_reset(mem);
|
||||
@ -2862,15 +2864,15 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
BIO_free(mem);
|
||||
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
result = verifyhost(conn, connssl->server_cert);
|
||||
result = verifyhost(conn, BACKEND->server_cert);
|
||||
if(result) {
|
||||
X509_free(connssl->server_cert);
|
||||
connssl->server_cert = NULL;
|
||||
X509_free(BACKEND->server_cert);
|
||||
BACKEND->server_cert = NULL;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert),
|
||||
rc = x509_name_oneline(X509_get_issuer_name(BACKEND->server_cert),
|
||||
buffer, sizeof(buffer));
|
||||
if(rc) {
|
||||
if(strict)
|
||||
@ -2890,8 +2892,8 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
if(strict)
|
||||
failf(data, "SSL: Unable to open issuer cert (%s)",
|
||||
SSL_SET_OPTION(issuercert));
|
||||
X509_free(connssl->server_cert);
|
||||
connssl->server_cert = NULL;
|
||||
X509_free(BACKEND->server_cert);
|
||||
BACKEND->server_cert = NULL;
|
||||
return CURLE_SSL_ISSUER_ERROR;
|
||||
}
|
||||
|
||||
@ -2900,7 +2902,7 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
if(strict)
|
||||
failf(data, "SSL: Unable to read issuer cert (%s)",
|
||||
SSL_SET_OPTION(issuercert));
|
||||
X509_free(connssl->server_cert);
|
||||
X509_free(BACKEND->server_cert);
|
||||
X509_free(issuer);
|
||||
fclose(fp);
|
||||
return CURLE_SSL_ISSUER_ERROR;
|
||||
@ -2908,13 +2910,13 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if(X509_check_issued(issuer, connssl->server_cert) != X509_V_OK) {
|
||||
if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) {
|
||||
if(strict)
|
||||
failf(data, "SSL: Certificate issuer check failed (%s)",
|
||||
SSL_SET_OPTION(issuercert));
|
||||
X509_free(connssl->server_cert);
|
||||
X509_free(BACKEND->server_cert);
|
||||
X509_free(issuer);
|
||||
connssl->server_cert = NULL;
|
||||
BACKEND->server_cert = NULL;
|
||||
return CURLE_SSL_ISSUER_ERROR;
|
||||
}
|
||||
|
||||
@ -2923,7 +2925,7 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
X509_free(issuer);
|
||||
}
|
||||
|
||||
lerr = *certverifyresult = SSL_get_verify_result(connssl->handle);
|
||||
lerr = *certverifyresult = SSL_get_verify_result(BACKEND->handle);
|
||||
|
||||
if(*certverifyresult != X509_V_OK) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
@ -2948,8 +2950,8 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
if(SSL_CONN_CONFIG(verifystatus)) {
|
||||
result = verifystatus(conn, connssl);
|
||||
if(result) {
|
||||
X509_free(connssl->server_cert);
|
||||
connssl->server_cert = NULL;
|
||||
X509_free(BACKEND->server_cert);
|
||||
BACKEND->server_cert = NULL;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -2962,13 +2964,13 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
|
||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
|
||||
if(!result && ptr) {
|
||||
result = pkp_pin_peer_pubkey(data, connssl->server_cert, ptr);
|
||||
result = pkp_pin_peer_pubkey(data, BACKEND->server_cert, ptr);
|
||||
if(result)
|
||||
failf(data, "SSL: public key does not match pinned public key!");
|
||||
}
|
||||
|
||||
X509_free(connssl->server_cert);
|
||||
connssl->server_cert = NULL;
|
||||
X509_free(BACKEND->server_cert);
|
||||
BACKEND->server_cert = NULL;
|
||||
connssl->connecting_state = ssl_connect_done;
|
||||
|
||||
return result;
|
||||
@ -2987,7 +2989,7 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
|
||||
SSL_SESSION *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
|
||||
our_ssl_sessionid = SSL_get1_session(connssl->handle);
|
||||
our_ssl_sessionid = SSL_get1_session(BACKEND->handle);
|
||||
|
||||
/* SSL_get1_session() will increment the reference count and the session
|
||||
will stay in memory until explicitly freed with SSL_SESSION_free(3),
|
||||
@ -3176,11 +3178,11 @@ static CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex)
|
||||
static bool Curl_ossl_data_pending(const struct connectdata *conn,
|
||||
int connindex)
|
||||
{
|
||||
if(conn->ssl[connindex].handle)
|
||||
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
|
||||
if(BACKEND->handle)
|
||||
/* SSL is in use */
|
||||
return (0 != SSL_pending(conn->ssl[connindex].handle) ||
|
||||
(conn->proxy_ssl[connindex].handle &&
|
||||
0 != SSL_pending(conn->proxy_ssl[connindex].handle))) ?
|
||||
return (0 != SSL_pending(BACKEND->handle) ||
|
||||
(BACKEND->handle && 0 != SSL_pending(BACKEND->handle))) ?
|
||||
TRUE : FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
@ -3200,14 +3202,15 @@ static ssize_t ossl_send(struct connectdata *conn,
|
||||
unsigned long sslerror;
|
||||
int memlen;
|
||||
int rc;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
|
||||
rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen);
|
||||
rc = SSL_write(BACKEND->handle, mem, memlen);
|
||||
|
||||
if(rc <= 0) {
|
||||
err = SSL_get_error(conn->ssl[sockindex].handle, rc);
|
||||
err = SSL_get_error(BACKEND->handle, rc);
|
||||
|
||||
switch(err) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
@ -3261,14 +3264,15 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
|
||||
unsigned long sslerror;
|
||||
ssize_t nread;
|
||||
int buffsize;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
|
||||
nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize);
|
||||
nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize);
|
||||
if(nread <= 0) {
|
||||
/* failed SSL_read */
|
||||
int err = SSL_get_error(conn->ssl[num].handle, (int)nread);
|
||||
int err = SSL_get_error(BACKEND->handle, (int)nread);
|
||||
|
||||
switch(err) {
|
||||
case SSL_ERROR_NONE: /* this is not an error */
|
||||
@ -3399,7 +3403,7 @@ static void *Curl_ossl_get_internals(struct ssl_connect_data *connssl,
|
||||
{
|
||||
/* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
|
||||
return info == CURLINFO_TLS_SESSION ?
|
||||
(void *)connssl->ctx : (void *)connssl->handle;
|
||||
(void *)BACKEND->ctx : (void *)BACKEND->handle;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_openssl = {
|
||||
|
@ -70,6 +70,8 @@
|
||||
#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
|
||||
RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
/* apply threading? */
|
||||
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
#define THREADING_SUPPORT
|
||||
@ -197,8 +199,8 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
|
||||
return result;
|
||||
}
|
||||
|
||||
ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver);
|
||||
ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver);
|
||||
ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver);
|
||||
ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -226,16 +228,16 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
#ifdef THREADING_SUPPORT
|
||||
entropy_init_mutex(&entropy);
|
||||
|
||||
if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy,
|
||||
if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy,
|
||||
NULL, 0)) != 0) {
|
||||
error_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
|
||||
-ret, errorbuf);
|
||||
}
|
||||
#else
|
||||
entropy_init(&connssl->entropy);
|
||||
entropy_init(&BACKEND->entropy);
|
||||
|
||||
if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy,
|
||||
if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy,
|
||||
NULL, 0)) != 0) {
|
||||
error_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
|
||||
@ -244,10 +246,10 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
#endif /* THREADING_SUPPORT */
|
||||
|
||||
/* Load the trusted CA */
|
||||
memset(&connssl->cacert, 0, sizeof(x509_crt));
|
||||
memset(&BACKEND->cacert, 0, sizeof(x509_crt));
|
||||
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
ret = x509_crt_parse_file(&connssl->cacert,
|
||||
ret = x509_crt_parse_file(&BACKEND->cacert,
|
||||
SSL_CONN_CONFIG(CAfile));
|
||||
|
||||
if(ret<0) {
|
||||
@ -261,7 +263,7 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(capath) {
|
||||
ret = x509_crt_parse_path(&connssl->cacert, capath);
|
||||
ret = x509_crt_parse_path(&BACKEND->cacert, capath);
|
||||
|
||||
if(ret<0) {
|
||||
error_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
@ -274,10 +276,10 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Load the client certificate */
|
||||
memset(&connssl->clicert, 0, sizeof(x509_crt));
|
||||
memset(&BACKEND->clicert, 0, sizeof(x509_crt));
|
||||
|
||||
if(SSL_SET_OPTION(cert)) {
|
||||
ret = x509_crt_parse_file(&connssl->clicert,
|
||||
ret = x509_crt_parse_file(&BACKEND->clicert,
|
||||
SSL_SET_OPTION(cert));
|
||||
|
||||
if(ret) {
|
||||
@ -298,9 +300,9 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
|
||||
ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
|
||||
if(ret == 0)
|
||||
rsa_copy(&connssl->rsa, pk_rsa(pk));
|
||||
rsa_copy(&BACKEND->rsa, pk_rsa(pk));
|
||||
else
|
||||
rsa_free(&connssl->rsa);
|
||||
rsa_free(&BACKEND->rsa);
|
||||
pk_free(&pk);
|
||||
|
||||
if(ret) {
|
||||
@ -313,10 +315,10 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Load the CRL */
|
||||
memset(&connssl->crl, 0, sizeof(x509_crl));
|
||||
memset(&BACKEND->crl, 0, sizeof(x509_crl));
|
||||
|
||||
if(SSL_SET_OPTION(CRLfile)) {
|
||||
ret = x509_crl_parse_file(&connssl->crl,
|
||||
ret = x509_crl_parse_file(&BACKEND->crl,
|
||||
SSL_SET_OPTION(CRLfile));
|
||||
|
||||
if(ret) {
|
||||
@ -330,7 +332,7 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
|
||||
infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port);
|
||||
|
||||
if(ssl_init(&connssl->ssl)) {
|
||||
if(ssl_init(&BACKEND->ssl)) {
|
||||
failf(data, "PolarSSL: ssl_init failed");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
@ -338,13 +340,13 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
switch(SSL_CONN_CONFIG(version)) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
|
||||
ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
|
||||
SSL_MINOR_VERSION_1);
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
|
||||
ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
|
||||
SSL_MINOR_VERSION_0);
|
||||
ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
|
||||
ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
|
||||
SSL_MINOR_VERSION_0);
|
||||
infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
|
||||
break;
|
||||
@ -363,16 +365,16 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT);
|
||||
ssl_set_authmode(&connssl->ssl, SSL_VERIFY_OPTIONAL);
|
||||
ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT);
|
||||
ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL);
|
||||
|
||||
ssl_set_rng(&connssl->ssl, ctr_drbg_random,
|
||||
&connssl->ctr_drbg);
|
||||
ssl_set_bio(&connssl->ssl,
|
||||
ssl_set_rng(&BACKEND->ssl, ctr_drbg_random,
|
||||
&BACKEND->ctr_drbg);
|
||||
ssl_set_bio(&BACKEND->ssl,
|
||||
net_recv, &conn->sock[sockindex],
|
||||
net_send, &conn->sock[sockindex]);
|
||||
|
||||
ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
|
||||
ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites());
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
@ -380,7 +382,7 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
|
||||
ret = ssl_set_session(&connssl->ssl, old_session);
|
||||
ret = ssl_set_session(&BACKEND->ssl, old_session);
|
||||
if(ret) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
failf(data, "ssl_set_session returned -0x%x", -ret);
|
||||
@ -391,15 +393,15 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
}
|
||||
|
||||
ssl_set_ca_chain(&connssl->ssl,
|
||||
&connssl->cacert,
|
||||
&connssl->crl,
|
||||
ssl_set_ca_chain(&BACKEND->ssl,
|
||||
&BACKEND->cacert,
|
||||
&BACKEND->crl,
|
||||
hostname);
|
||||
|
||||
ssl_set_own_cert_rsa(&connssl->ssl,
|
||||
&connssl->clicert, &connssl->rsa);
|
||||
ssl_set_own_cert_rsa(&BACKEND->ssl,
|
||||
&BACKEND->clicert, &BACKEND->rsa);
|
||||
|
||||
if(ssl_set_hostname(&connssl->ssl, hostname)) {
|
||||
if(ssl_set_hostname(&BACKEND->ssl, hostname)) {
|
||||
/* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name
|
||||
to set in the SNI extension. So even if curl connects to a host
|
||||
specified as an IP address, this function must be used. */
|
||||
@ -424,12 +426,12 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
|
||||
protocols[cur] = NULL;
|
||||
|
||||
ssl_set_alpn_protocols(&connssl->ssl, protocols);
|
||||
ssl_set_alpn_protocols(&BACKEND->ssl, protocols);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef POLARSSL_DEBUG
|
||||
ssl_set_dbg(&connssl->ssl, polarssl_debug, data);
|
||||
ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data);
|
||||
#endif
|
||||
|
||||
connssl->connecting_state = ssl_connect_2;
|
||||
@ -443,7 +445,7 @@ polarssl_connect_step2(struct connectdata *conn,
|
||||
{
|
||||
int ret;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
|
||||
struct ssl_connect_data* connssl = &BACKEND->ssl[sockindex];
|
||||
char buffer[1024];
|
||||
const char * const pinnedpubkey = SSL_IS_PROXY() ?
|
||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
|
||||
@ -456,7 +458,7 @@ polarssl_connect_step2(struct connectdata *conn,
|
||||
conn->recv[sockindex] = polarssl_recv;
|
||||
conn->send[sockindex] = polarssl_send;
|
||||
|
||||
ret = ssl_handshake(&connssl->ssl);
|
||||
ret = ssl_handshake(&BACKEND->ssl);
|
||||
|
||||
switch(ret) {
|
||||
case 0:
|
||||
@ -478,9 +480,9 @@ polarssl_connect_step2(struct connectdata *conn,
|
||||
}
|
||||
|
||||
infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
|
||||
ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) );
|
||||
ssl_get_ciphersuite(&BACKEND->ssl) );
|
||||
|
||||
ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl);
|
||||
ret = ssl_get_verify_result(&BACKEND->ssl);
|
||||
|
||||
if(ret && SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(ret & BADCERT_EXPIRED)
|
||||
@ -500,12 +502,12 @@ polarssl_connect_step2(struct connectdata *conn,
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
|
||||
if(ssl_get_peer_cert(&(connssl->ssl))) {
|
||||
if(ssl_get_peer_cert(&(BACKEND->ssl))) {
|
||||
/* If the session was resumed, there will be no peer certs */
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
|
||||
ssl_get_peer_cert(&(connssl->ssl))) != -1)
|
||||
ssl_get_peer_cert(&(BACKEND->ssl))) != -1)
|
||||
infof(data, "Dumping cert info:\n%s\n", buffer);
|
||||
}
|
||||
|
||||
@ -517,7 +519,7 @@ polarssl_connect_step2(struct connectdata *conn,
|
||||
unsigned char pubkey[PUB_DER_MAX_BYTES];
|
||||
const x509_crt *peercert;
|
||||
|
||||
peercert = ssl_get_peer_cert(&connssl->ssl);
|
||||
peercert = ssl_get_peer_cert(&BACKEND->ssl);
|
||||
|
||||
if(!peercert || !peercert->raw.p || !peercert->raw.len) {
|
||||
failf(data, "Failed due to missing peer certificate");
|
||||
@ -566,7 +568,7 @@ polarssl_connect_step2(struct connectdata *conn,
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
const char *next_protocol = ssl_get_alpn_protocol(&connssl->ssl);
|
||||
const char *next_protocol = ssl_get_alpn_protocol(&BACKEND->ssl);
|
||||
|
||||
if(next_protocol != NULL) {
|
||||
infof(data, "ALPN, server accepted to use %s\n", next_protocol);
|
||||
@ -614,7 +616,7 @@ polarssl_connect_step3(struct connectdata *conn,
|
||||
|
||||
memset(our_ssl_sessionid, 0, sizeof(ssl_session));
|
||||
|
||||
ret = ssl_get_session(&connssl->ssl, our_ssl_sessionid);
|
||||
ret = ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
|
||||
if(ret) {
|
||||
failf(data, "ssl_get_session returned -0x%x", -ret);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@ -645,9 +647,10 @@ static ssize_t polarssl_send(struct connectdata *conn,
|
||||
size_t len,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
int ret = -1;
|
||||
|
||||
ret = ssl_write(&conn->ssl[sockindex].ssl,
|
||||
ret = ssl_write(&BACKEND->ssl,
|
||||
(unsigned char *)mem, len);
|
||||
|
||||
if(ret < 0) {
|
||||
@ -661,11 +664,12 @@ static ssize_t polarssl_send(struct connectdata *conn,
|
||||
|
||||
static void Curl_polarssl_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
rsa_free(&conn->ssl[sockindex].rsa);
|
||||
x509_crt_free(&conn->ssl[sockindex].clicert);
|
||||
x509_crt_free(&conn->ssl[sockindex].cacert);
|
||||
x509_crl_free(&conn->ssl[sockindex].crl);
|
||||
ssl_free(&conn->ssl[sockindex].ssl);
|
||||
struct ssl_connect_data *connssl = &conn->sock[sockindex];
|
||||
rsa_free(&BACKEND->rsa);
|
||||
x509_crt_free(&BACKEND->clicert);
|
||||
x509_crt_free(&BACKEND->cacert);
|
||||
x509_crl_free(&BACKEND->crl);
|
||||
ssl_free(&BACKEND->ssl);
|
||||
}
|
||||
|
||||
static ssize_t polarssl_recv(struct connectdata *conn,
|
||||
@ -674,11 +678,12 @@ static ssize_t polarssl_recv(struct connectdata *conn,
|
||||
size_t buffersize,
|
||||
CURLcode *curlcode)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
int ret = -1;
|
||||
ssize_t len = -1;
|
||||
|
||||
memset(buf, 0, buffersize);
|
||||
ret = ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf, buffersize);
|
||||
ret = ssl_read(&BACKEND->ssl, (unsigned char *)buf, buffersize);
|
||||
|
||||
if(ret <= 0) {
|
||||
if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
|
||||
@ -863,7 +868,8 @@ static void Curl_polarssl_cleanup(void)
|
||||
static bool Curl_polarssl_data_pending(const struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
return ssl_get_bytes_avail(&conn->ssl[sockindex].ssl) != 0;
|
||||
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
return ssl_get_bytes_avail(&BACKEND->ssl) != 0;
|
||||
}
|
||||
|
||||
static void Curl_polarssl_sha256sum(const unsigned char *input,
|
||||
@ -878,7 +884,7 @@ static void *Curl_polarssl_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return &connssl->ssl;
|
||||
return &BACKEND->ssl;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_polarssl = {
|
||||
|
@ -127,6 +127,8 @@
|
||||
* #define failf(x, y, ...) printf(y, __VA_ARGS__)
|
||||
*/
|
||||
|
||||
#define BACKEND connssl
|
||||
|
||||
static Curl_recv schannel_recv;
|
||||
static Curl_send schannel_send;
|
||||
|
||||
@ -224,33 +226,33 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
#ifdef HAS_ALPN
|
||||
/* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
|
||||
Also it doesn't seem to be supported for Wine, see curl bug #983. */
|
||||
connssl->use_alpn = conn->bits.tls_enable_alpn &&
|
||||
BACKEND->use_alpn = conn->bits.tls_enable_alpn &&
|
||||
!GetProcAddress(GetModuleHandleA("ntdll"),
|
||||
"wine_get_version") &&
|
||||
Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL);
|
||||
#else
|
||||
connssl->use_alpn = false;
|
||||
BACKEND->use_alpn = false;
|
||||
#endif
|
||||
|
||||
connssl->cred = NULL;
|
||||
BACKEND->cred = NULL;
|
||||
|
||||
/* check for an existing re-usable credential handle */
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
|
||||
connssl->cred = old_cred;
|
||||
BACKEND->cred = old_cred;
|
||||
infof(data, "schannel: re-using existing credential handle\n");
|
||||
|
||||
/* increment the reference counter of the credential/session handle */
|
||||
connssl->cred->refcount++;
|
||||
BACKEND->cred->refcount++;
|
||||
infof(data, "schannel: incremented credential handle refcount = %d\n",
|
||||
connssl->cred->refcount);
|
||||
BACKEND->cred->refcount);
|
||||
}
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
}
|
||||
|
||||
if(!connssl->cred) {
|
||||
if(!BACKEND->cred) {
|
||||
/* setup Schannel API options */
|
||||
memset(&schannel_cred, 0, sizeof(schannel_cred));
|
||||
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
|
||||
@ -320,14 +322,14 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* allocate memory for the re-usable credential handle */
|
||||
connssl->cred = (struct curl_schannel_cred *)
|
||||
BACKEND->cred = (struct curl_schannel_cred *)
|
||||
malloc(sizeof(struct curl_schannel_cred));
|
||||
if(!connssl->cred) {
|
||||
if(!BACKEND->cred) {
|
||||
failf(data, "schannel: unable to allocate memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
memset(connssl->cred, 0, sizeof(struct curl_schannel_cred));
|
||||
connssl->cred->refcount = 1;
|
||||
memset(BACKEND->cred, 0, sizeof(struct curl_schannel_cred));
|
||||
BACKEND->cred->refcount = 1;
|
||||
|
||||
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx
|
||||
*/
|
||||
@ -335,8 +337,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
&schannel_cred, NULL, NULL,
|
||||
&connssl->cred->cred_handle,
|
||||
&connssl->cred->time_stamp);
|
||||
&BACKEND->cred->cred_handle,
|
||||
&BACKEND->cred->time_stamp);
|
||||
|
||||
if(sspi_status != SEC_E_OK) {
|
||||
if(sspi_status == SEC_E_WRONG_PRINCIPAL)
|
||||
@ -345,7 +347,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
else
|
||||
failf(data, "schannel: AcquireCredentialsHandle failed: %s",
|
||||
Curl_sspi_strerror(conn, sspi_status));
|
||||
Curl_safefree(connssl->cred);
|
||||
Curl_safefree(BACKEND->cred);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
@ -360,7 +362,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(connssl->use_alpn) {
|
||||
if(BACKEND->use_alpn) {
|
||||
int cur = 0;
|
||||
int list_start_index = 0;
|
||||
unsigned int *extension_len = NULL;
|
||||
@ -418,18 +420,18 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
|
||||
|
||||
/* setup request flags */
|
||||
connssl->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
|
||||
BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
|
||||
ISC_REQ_STREAM;
|
||||
|
||||
/* allocate memory for the security context handle */
|
||||
connssl->ctxt = (struct curl_schannel_ctxt *)
|
||||
BACKEND->ctxt = (struct curl_schannel_ctxt *)
|
||||
malloc(sizeof(struct curl_schannel_ctxt));
|
||||
if(!connssl->ctxt) {
|
||||
if(!BACKEND->ctxt) {
|
||||
failf(data, "schannel: unable to allocate memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
memset(connssl->ctxt, 0, sizeof(struct curl_schannel_ctxt));
|
||||
memset(BACKEND->ctxt, 0, sizeof(struct curl_schannel_ctxt));
|
||||
|
||||
host_name = Curl_convert_UTF8_to_tchar(hostname);
|
||||
if(!host_name)
|
||||
@ -443,10 +445,10 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
us problems with inbuf regardless. https://github.com/curl/curl/issues/983
|
||||
*/
|
||||
sspi_status = s_pSecFn->InitializeSecurityContext(
|
||||
&connssl->cred->cred_handle, NULL, host_name, connssl->req_flags, 0, 0,
|
||||
(connssl->use_alpn ? &inbuf_desc : NULL),
|
||||
0, &connssl->ctxt->ctxt_handle,
|
||||
&outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
|
||||
&BACKEND->cred->cred_handle, NULL, host_name, BACKEND->req_flags, 0, 0,
|
||||
(BACKEND->use_alpn ? &inbuf_desc : NULL),
|
||||
0, &BACKEND->ctxt->ctxt_handle,
|
||||
&outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
|
||||
|
||||
Curl_unicodefree(host_name);
|
||||
|
||||
@ -457,7 +459,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
else
|
||||
failf(data, "schannel: initial InitializeSecurityContext failed: %s",
|
||||
Curl_sspi_strerror(conn, sspi_status));
|
||||
Curl_safefree(connssl->ctxt);
|
||||
Curl_safefree(BACKEND->ctxt);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
@ -477,10 +479,10 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
infof(data, "schannel: sent initial handshake data: "
|
||||
"sent %zd bytes\n", written);
|
||||
|
||||
connssl->recv_unrecoverable_err = CURLE_OK;
|
||||
connssl->recv_sspi_close_notify = false;
|
||||
connssl->recv_connection_closed = false;
|
||||
connssl->encdata_is_incomplete = false;
|
||||
BACKEND->recv_unrecoverable_err = CURLE_OK;
|
||||
BACKEND->recv_sspi_close_notify = false;
|
||||
BACKEND->recv_connection_closed = false;
|
||||
BACKEND->encdata_is_incomplete = false;
|
||||
|
||||
/* continue to second handshake step */
|
||||
connssl->connecting_state = ssl_connect_2;
|
||||
@ -513,39 +515,39 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
|
||||
hostname, conn->remote_port);
|
||||
|
||||
if(!connssl->cred || !connssl->ctxt)
|
||||
if(!BACKEND->cred || !BACKEND->ctxt)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
/* buffer to store previously received and decrypted data */
|
||||
if(connssl->decdata_buffer == NULL) {
|
||||
connssl->decdata_offset = 0;
|
||||
connssl->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
|
||||
connssl->decdata_buffer = malloc(connssl->decdata_length);
|
||||
if(connssl->decdata_buffer == NULL) {
|
||||
if(BACKEND->decdata_buffer == NULL) {
|
||||
BACKEND->decdata_offset = 0;
|
||||
BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
|
||||
BACKEND->decdata_buffer = malloc(BACKEND->decdata_length);
|
||||
if(BACKEND->decdata_buffer == NULL) {
|
||||
failf(data, "schannel: unable to allocate memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* buffer to store previously received and encrypted data */
|
||||
if(connssl->encdata_buffer == NULL) {
|
||||
connssl->encdata_is_incomplete = false;
|
||||
connssl->encdata_offset = 0;
|
||||
connssl->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
|
||||
connssl->encdata_buffer = malloc(connssl->encdata_length);
|
||||
if(connssl->encdata_buffer == NULL) {
|
||||
if(BACKEND->encdata_buffer == NULL) {
|
||||
BACKEND->encdata_is_incomplete = false;
|
||||
BACKEND->encdata_offset = 0;
|
||||
BACKEND->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
|
||||
BACKEND->encdata_buffer = malloc(BACKEND->encdata_length);
|
||||
if(BACKEND->encdata_buffer == NULL) {
|
||||
failf(data, "schannel: unable to allocate memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we need a bigger buffer to read a full message, increase buffer now */
|
||||
if(connssl->encdata_length - connssl->encdata_offset <
|
||||
if(BACKEND->encdata_length - BACKEND->encdata_offset <
|
||||
CURL_SCHANNEL_BUFFER_FREE_SIZE) {
|
||||
/* increase internal encrypted data buffer */
|
||||
reallocated_length = connssl->encdata_offset +
|
||||
reallocated_length = BACKEND->encdata_offset +
|
||||
CURL_SCHANNEL_BUFFER_FREE_SIZE;
|
||||
reallocated_buffer = realloc(connssl->encdata_buffer,
|
||||
reallocated_buffer = realloc(BACKEND->encdata_buffer,
|
||||
reallocated_length);
|
||||
|
||||
if(reallocated_buffer == NULL) {
|
||||
@ -553,8 +555,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
connssl->encdata_buffer = reallocated_buffer;
|
||||
connssl->encdata_length = reallocated_length;
|
||||
BACKEND->encdata_buffer = reallocated_buffer;
|
||||
BACKEND->encdata_length = reallocated_length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -562,10 +564,10 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
if(doread) {
|
||||
/* read encrypted handshake data from socket */
|
||||
result = Curl_read_plain(conn->sock[sockindex],
|
||||
(char *) (connssl->encdata_buffer +
|
||||
connssl->encdata_offset),
|
||||
connssl->encdata_length -
|
||||
connssl->encdata_offset,
|
||||
(char *) (BACKEND->encdata_buffer +
|
||||
BACKEND->encdata_offset),
|
||||
BACKEND->encdata_length -
|
||||
BACKEND->encdata_offset,
|
||||
&nread);
|
||||
if(result == CURLE_AGAIN) {
|
||||
if(connssl->connecting_state != ssl_connect_2_writing)
|
||||
@ -581,17 +583,17 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* increase encrypted data buffer offset */
|
||||
connssl->encdata_offset += nread;
|
||||
connssl->encdata_is_incomplete = false;
|
||||
BACKEND->encdata_offset += nread;
|
||||
BACKEND->encdata_is_incomplete = false;
|
||||
infof(data, "schannel: encrypted data got %zd\n", nread);
|
||||
}
|
||||
|
||||
infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
|
||||
connssl->encdata_offset, connssl->encdata_length);
|
||||
BACKEND->encdata_offset, BACKEND->encdata_length);
|
||||
|
||||
/* setup input buffers */
|
||||
InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(connssl->encdata_offset),
|
||||
curlx_uztoul(connssl->encdata_offset));
|
||||
InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset),
|
||||
curlx_uztoul(BACKEND->encdata_offset));
|
||||
InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
|
||||
InitSecBufferDesc(&inbuf_desc, inbuf, 2);
|
||||
|
||||
@ -607,8 +609,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* copy received handshake data into input buffer */
|
||||
memcpy(inbuf[0].pvBuffer, connssl->encdata_buffer,
|
||||
connssl->encdata_offset);
|
||||
memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer,
|
||||
BACKEND->encdata_offset);
|
||||
|
||||
host_name = Curl_convert_UTF8_to_tchar(hostname);
|
||||
if(!host_name)
|
||||
@ -617,9 +619,9 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
|
||||
*/
|
||||
sspi_status = s_pSecFn->InitializeSecurityContext(
|
||||
&connssl->cred->cred_handle, &connssl->ctxt->ctxt_handle,
|
||||
host_name, connssl->req_flags, 0, 0, &inbuf_desc, 0, NULL,
|
||||
&outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
|
||||
&BACKEND->cred->cred_handle, &BACKEND->ctxt->ctxt_handle,
|
||||
host_name, BACKEND->req_flags, 0, 0, &inbuf_desc, 0, NULL,
|
||||
&outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
|
||||
|
||||
Curl_unicodefree(host_name);
|
||||
|
||||
@ -628,7 +630,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* check if the handshake was incomplete */
|
||||
if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
|
||||
connssl->encdata_is_incomplete = true;
|
||||
BACKEND->encdata_is_incomplete = true;
|
||||
connssl->connecting_state = ssl_connect_2_reading;
|
||||
infof(data, "schannel: received incomplete message, need more data\n");
|
||||
return CURLE_OK;
|
||||
@ -638,8 +640,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
the handshake without one. This will allow connections to servers which
|
||||
request a client certificate but do not require it. */
|
||||
if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
|
||||
!(connssl->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
|
||||
connssl->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
|
||||
!(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
|
||||
BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
|
||||
connssl->connecting_state = ssl_connect_2_writing;
|
||||
infof(data, "schannel: a client certificate has been requested\n");
|
||||
return CURLE_OK;
|
||||
@ -697,11 +699,11 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
*/
|
||||
/* check if the remaining data is less than the total amount
|
||||
and therefore begins after the already processed data */
|
||||
if(connssl->encdata_offset > inbuf[1].cbBuffer) {
|
||||
memmove(connssl->encdata_buffer,
|
||||
(connssl->encdata_buffer + connssl->encdata_offset) -
|
||||
if(BACKEND->encdata_offset > inbuf[1].cbBuffer) {
|
||||
memmove(BACKEND->encdata_buffer,
|
||||
(BACKEND->encdata_buffer + BACKEND->encdata_offset) -
|
||||
inbuf[1].cbBuffer, inbuf[1].cbBuffer);
|
||||
connssl->encdata_offset = inbuf[1].cbBuffer;
|
||||
BACKEND->encdata_offset = inbuf[1].cbBuffer;
|
||||
if(sspi_status == SEC_I_CONTINUE_NEEDED) {
|
||||
doread = FALSE;
|
||||
continue;
|
||||
@ -709,7 +711,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
}
|
||||
else {
|
||||
connssl->encdata_offset = 0;
|
||||
BACKEND->encdata_offset = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -757,27 +759,27 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
|
||||
hostname, conn->remote_port);
|
||||
|
||||
if(!connssl->cred)
|
||||
if(!BACKEND->cred)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
/* check if the required context attributes are met */
|
||||
if(connssl->ret_flags != connssl->req_flags) {
|
||||
if(!(connssl->ret_flags & ISC_RET_SEQUENCE_DETECT))
|
||||
if(BACKEND->ret_flags != BACKEND->req_flags) {
|
||||
if(!(BACKEND->ret_flags & ISC_RET_SEQUENCE_DETECT))
|
||||
failf(data, "schannel: failed to setup sequence detection");
|
||||
if(!(connssl->ret_flags & ISC_RET_REPLAY_DETECT))
|
||||
if(!(BACKEND->ret_flags & ISC_RET_REPLAY_DETECT))
|
||||
failf(data, "schannel: failed to setup replay detection");
|
||||
if(!(connssl->ret_flags & ISC_RET_CONFIDENTIALITY))
|
||||
if(!(BACKEND->ret_flags & ISC_RET_CONFIDENTIALITY))
|
||||
failf(data, "schannel: failed to setup confidentiality");
|
||||
if(!(connssl->ret_flags & ISC_RET_ALLOCATED_MEMORY))
|
||||
if(!(BACKEND->ret_flags & ISC_RET_ALLOCATED_MEMORY))
|
||||
failf(data, "schannel: failed to setup memory allocation");
|
||||
if(!(connssl->ret_flags & ISC_RET_STREAM))
|
||||
if(!(BACKEND->ret_flags & ISC_RET_STREAM))
|
||||
failf(data, "schannel: failed to setup stream orientation");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(connssl->use_alpn) {
|
||||
sspi_status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
|
||||
if(BACKEND->use_alpn) {
|
||||
sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
|
||||
SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result);
|
||||
|
||||
if(sspi_status != SEC_E_OK) {
|
||||
@ -819,7 +821,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL,
|
||||
sockindex));
|
||||
if(incache) {
|
||||
if(old_cred != connssl->cred) {
|
||||
if(old_cred != BACKEND->cred) {
|
||||
infof(data, "schannel: old credential handle is stale, removing\n");
|
||||
/* we're not taking old_cred ownership here, no refcount++ is needed */
|
||||
Curl_ssl_delsessionid(conn, (void *)old_cred);
|
||||
@ -827,7 +829,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
}
|
||||
if(!incache) {
|
||||
result = Curl_ssl_addsessionid(conn, (void *)connssl->cred,
|
||||
result = Curl_ssl_addsessionid(conn, (void *)BACKEND->cred,
|
||||
sizeof(struct curl_schannel_cred),
|
||||
sockindex);
|
||||
if(result) {
|
||||
@ -837,7 +839,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
else {
|
||||
/* this cred session is now also referenced by sessionid cache */
|
||||
connssl->cred->refcount++;
|
||||
BACKEND->cred->refcount++;
|
||||
infof(data, "schannel: stored credential handle in session cache\n");
|
||||
}
|
||||
}
|
||||
@ -845,7 +847,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
if(data->set.ssl.certinfo) {
|
||||
sspi_status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
|
||||
sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
|
||||
SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context);
|
||||
|
||||
if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) {
|
||||
@ -999,11 +1001,11 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
CURLcode result;
|
||||
|
||||
/* check if the maximum stream sizes were queried */
|
||||
if(connssl->stream_sizes.cbMaximumMessage == 0) {
|
||||
if(BACKEND->stream_sizes.cbMaximumMessage == 0) {
|
||||
sspi_status = s_pSecFn->QueryContextAttributes(
|
||||
&connssl->ctxt->ctxt_handle,
|
||||
&BACKEND->ctxt->ctxt_handle,
|
||||
SECPKG_ATTR_STREAM_SIZES,
|
||||
&connssl->stream_sizes);
|
||||
&BACKEND->stream_sizes);
|
||||
if(sspi_status != SEC_E_OK) {
|
||||
*err = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
@ -1011,14 +1013,14 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
|
||||
/* check if the buffer is longer than the maximum message length */
|
||||
if(len > connssl->stream_sizes.cbMaximumMessage) {
|
||||
if(len > BACKEND->stream_sizes.cbMaximumMessage) {
|
||||
*err = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* calculate the complete message length and allocate a buffer for it */
|
||||
data_len = connssl->stream_sizes.cbHeader + len +
|
||||
connssl->stream_sizes.cbTrailer;
|
||||
data_len = BACKEND->stream_sizes.cbHeader + len +
|
||||
BACKEND->stream_sizes.cbTrailer;
|
||||
data = (unsigned char *) malloc(data_len);
|
||||
if(data == NULL) {
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
@ -1027,12 +1029,12 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
|
||||
/* setup output buffers (header, data, trailer, empty) */
|
||||
InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
|
||||
data, connssl->stream_sizes.cbHeader);
|
||||
data, BACKEND->stream_sizes.cbHeader);
|
||||
InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
|
||||
data + connssl->stream_sizes.cbHeader, curlx_uztoul(len));
|
||||
data + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
|
||||
InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
|
||||
data + connssl->stream_sizes.cbHeader + len,
|
||||
connssl->stream_sizes.cbTrailer);
|
||||
data + BACKEND->stream_sizes.cbHeader + len,
|
||||
BACKEND->stream_sizes.cbTrailer);
|
||||
InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
|
||||
InitSecBufferDesc(&outbuf_desc, outbuf, 4);
|
||||
|
||||
@ -1040,7 +1042,7 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
memcpy(outbuf[1].pvBuffer, buf, len);
|
||||
|
||||
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
|
||||
sspi_status = s_pSecFn->EncryptMessage(&connssl->ctxt->ctxt_handle, 0,
|
||||
sspi_status = s_pSecFn->EncryptMessage(&BACKEND->ctxt->ctxt_handle, 0,
|
||||
&outbuf_desc, 0);
|
||||
|
||||
/* check if the message was encrypted */
|
||||
@ -1150,7 +1152,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
|
||||
|
||||
/****************************************************************************
|
||||
* Don't return or set connssl->recv_unrecoverable_err unless in the cleanup.
|
||||
* Don't return or set BACKEND->recv_unrecoverable_err unless in the cleanup.
|
||||
* The pattern for return error is set *err, optional infof, goto cleanup.
|
||||
*
|
||||
* Our priority is to always return as much decrypted data to the caller as
|
||||
@ -1162,16 +1164,16 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
infof(data, "schannel: client wants to read %zu bytes\n", len);
|
||||
*err = CURLE_OK;
|
||||
|
||||
if(len && len <= connssl->decdata_offset) {
|
||||
if(len && len <= BACKEND->decdata_offset) {
|
||||
infof(data, "schannel: enough decrypted data is already available\n");
|
||||
goto cleanup;
|
||||
}
|
||||
else if(connssl->recv_unrecoverable_err) {
|
||||
*err = connssl->recv_unrecoverable_err;
|
||||
else if(BACKEND->recv_unrecoverable_err) {
|
||||
*err = BACKEND->recv_unrecoverable_err;
|
||||
infof(data, "schannel: an unrecoverable error occurred in a prior call\n");
|
||||
goto cleanup;
|
||||
}
|
||||
else if(connssl->recv_sspi_close_notify) {
|
||||
else if(BACKEND->recv_sspi_close_notify) {
|
||||
/* once a server has indicated shutdown there is no more encrypted data */
|
||||
infof(data, "schannel: server indicated shutdown in a prior call\n");
|
||||
goto cleanup;
|
||||
@ -1183,17 +1185,17 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
*/
|
||||
; /* do nothing */
|
||||
}
|
||||
else if(!connssl->recv_connection_closed) {
|
||||
else if(!BACKEND->recv_connection_closed) {
|
||||
/* increase enc buffer in order to fit the requested amount of data */
|
||||
size = connssl->encdata_length - connssl->encdata_offset;
|
||||
size = BACKEND->encdata_length - BACKEND->encdata_offset;
|
||||
if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
|
||||
connssl->encdata_length < min_encdata_length) {
|
||||
reallocated_length = connssl->encdata_offset +
|
||||
BACKEND->encdata_length < min_encdata_length) {
|
||||
reallocated_length = BACKEND->encdata_offset +
|
||||
CURL_SCHANNEL_BUFFER_FREE_SIZE;
|
||||
if(reallocated_length < min_encdata_length) {
|
||||
reallocated_length = min_encdata_length;
|
||||
}
|
||||
reallocated_buffer = realloc(connssl->encdata_buffer,
|
||||
reallocated_buffer = realloc(BACKEND->encdata_buffer,
|
||||
reallocated_length);
|
||||
if(reallocated_buffer == NULL) {
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
@ -1201,20 +1203,20 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
connssl->encdata_buffer = reallocated_buffer;
|
||||
connssl->encdata_length = reallocated_length;
|
||||
size = connssl->encdata_length - connssl->encdata_offset;
|
||||
BACKEND->encdata_buffer = reallocated_buffer;
|
||||
BACKEND->encdata_length = reallocated_length;
|
||||
size = BACKEND->encdata_length - BACKEND->encdata_offset;
|
||||
infof(data, "schannel: encdata_buffer resized %zu\n",
|
||||
connssl->encdata_length);
|
||||
BACKEND->encdata_length);
|
||||
}
|
||||
|
||||
infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
|
||||
connssl->encdata_offset, connssl->encdata_length);
|
||||
BACKEND->encdata_offset, BACKEND->encdata_length);
|
||||
|
||||
/* read encrypted data from socket */
|
||||
*err = Curl_read_plain(conn->sock[sockindex],
|
||||
(char *)(connssl->encdata_buffer +
|
||||
connssl->encdata_offset),
|
||||
(char *)(BACKEND->encdata_buffer +
|
||||
BACKEND->encdata_offset),
|
||||
size, &nread);
|
||||
if(*err) {
|
||||
nread = -1;
|
||||
@ -1226,26 +1228,26 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
infof(data, "schannel: Curl_read_plain returned error %d\n", *err);
|
||||
}
|
||||
else if(nread == 0) {
|
||||
connssl->recv_connection_closed = true;
|
||||
BACKEND->recv_connection_closed = true;
|
||||
infof(data, "schannel: server closed the connection\n");
|
||||
}
|
||||
else if(nread > 0) {
|
||||
connssl->encdata_offset += (size_t)nread;
|
||||
connssl->encdata_is_incomplete = false;
|
||||
BACKEND->encdata_offset += (size_t)nread;
|
||||
BACKEND->encdata_is_incomplete = false;
|
||||
infof(data, "schannel: encrypted data got %zd\n", nread);
|
||||
}
|
||||
}
|
||||
|
||||
infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
|
||||
connssl->encdata_offset, connssl->encdata_length);
|
||||
BACKEND->encdata_offset, BACKEND->encdata_length);
|
||||
|
||||
/* decrypt loop */
|
||||
while(connssl->encdata_offset > 0 && sspi_status == SEC_E_OK &&
|
||||
(!len || connssl->decdata_offset < len ||
|
||||
connssl->recv_connection_closed)) {
|
||||
while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK &&
|
||||
(!len || BACKEND->decdata_offset < len ||
|
||||
BACKEND->recv_connection_closed)) {
|
||||
/* prepare data buffer for DecryptMessage call */
|
||||
InitSecBuffer(&inbuf[0], SECBUFFER_DATA, connssl->encdata_buffer,
|
||||
curlx_uztoul(connssl->encdata_offset));
|
||||
InitSecBuffer(&inbuf[0], SECBUFFER_DATA, BACKEND->encdata_buffer,
|
||||
curlx_uztoul(BACKEND->encdata_offset));
|
||||
|
||||
/* we need 3 more empty input buffers for possible output */
|
||||
InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
|
||||
@ -1255,7 +1257,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
|
||||
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
|
||||
*/
|
||||
sspi_status = s_pSecFn->DecryptMessage(&connssl->ctxt->ctxt_handle,
|
||||
sspi_status = s_pSecFn->DecryptMessage(&BACKEND->ctxt->ctxt_handle,
|
||||
&inbuf_desc, 0, NULL);
|
||||
|
||||
/* check if everything went fine (server may want to renegotiate
|
||||
@ -1271,36 +1273,36 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
/* increase buffer in order to fit the received amount of data */
|
||||
size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
|
||||
inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
|
||||
if(connssl->decdata_length - connssl->decdata_offset < size ||
|
||||
connssl->decdata_length < len) {
|
||||
if(BACKEND->decdata_length - BACKEND->decdata_offset < size ||
|
||||
BACKEND->decdata_length < len) {
|
||||
/* increase internal decrypted data buffer */
|
||||
reallocated_length = connssl->decdata_offset + size;
|
||||
reallocated_length = BACKEND->decdata_offset + size;
|
||||
/* make sure that the requested amount of data fits */
|
||||
if(reallocated_length < len) {
|
||||
reallocated_length = len;
|
||||
}
|
||||
reallocated_buffer = realloc(connssl->decdata_buffer,
|
||||
reallocated_buffer = realloc(BACKEND->decdata_buffer,
|
||||
reallocated_length);
|
||||
if(reallocated_buffer == NULL) {
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
failf(data, "schannel: unable to re-allocate memory");
|
||||
goto cleanup;
|
||||
}
|
||||
connssl->decdata_buffer = reallocated_buffer;
|
||||
connssl->decdata_length = reallocated_length;
|
||||
BACKEND->decdata_buffer = reallocated_buffer;
|
||||
BACKEND->decdata_length = reallocated_length;
|
||||
}
|
||||
|
||||
/* copy decrypted data to internal buffer */
|
||||
size = inbuf[1].cbBuffer;
|
||||
if(size) {
|
||||
memcpy(connssl->decdata_buffer + connssl->decdata_offset,
|
||||
memcpy(BACKEND->decdata_buffer + BACKEND->decdata_offset,
|
||||
inbuf[1].pvBuffer, size);
|
||||
connssl->decdata_offset += size;
|
||||
BACKEND->decdata_offset += size;
|
||||
}
|
||||
|
||||
infof(data, "schannel: decrypted data added: %zu\n", size);
|
||||
infof(data, "schannel: decrypted data cached: offset %zu length %zu\n",
|
||||
connssl->decdata_offset, connssl->decdata_length);
|
||||
BACKEND->decdata_offset, BACKEND->decdata_length);
|
||||
}
|
||||
|
||||
/* check for remaining encrypted data */
|
||||
@ -1311,21 +1313,21 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
/* check if the remaining data is less than the total amount
|
||||
* and therefore begins after the already processed data
|
||||
*/
|
||||
if(connssl->encdata_offset > inbuf[3].cbBuffer) {
|
||||
if(BACKEND->encdata_offset > inbuf[3].cbBuffer) {
|
||||
/* move remaining encrypted data forward to the beginning of
|
||||
buffer */
|
||||
memmove(connssl->encdata_buffer,
|
||||
(connssl->encdata_buffer + connssl->encdata_offset) -
|
||||
memmove(BACKEND->encdata_buffer,
|
||||
(BACKEND->encdata_buffer + BACKEND->encdata_offset) -
|
||||
inbuf[3].cbBuffer, inbuf[3].cbBuffer);
|
||||
connssl->encdata_offset = inbuf[3].cbBuffer;
|
||||
BACKEND->encdata_offset = inbuf[3].cbBuffer;
|
||||
}
|
||||
|
||||
infof(data, "schannel: encrypted data cached: offset %zu length %zu\n",
|
||||
connssl->encdata_offset, connssl->encdata_length);
|
||||
BACKEND->encdata_offset, BACKEND->encdata_length);
|
||||
}
|
||||
else {
|
||||
/* reset encrypted buffer offset, because there is no data remaining */
|
||||
connssl->encdata_offset = 0;
|
||||
BACKEND->encdata_offset = 0;
|
||||
}
|
||||
|
||||
/* check if server wants to renegotiate the connection context */
|
||||
@ -1335,7 +1337,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
infof(data, "schannel: can't renogotiate, an error is pending\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if(connssl->encdata_offset) {
|
||||
if(BACKEND->encdata_offset) {
|
||||
*err = CURLE_RECV_ERROR;
|
||||
infof(data, "schannel: can't renogotiate, "
|
||||
"encrypted data available\n");
|
||||
@ -1359,16 +1361,16 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
else if(sspi_status == SEC_I_CONTEXT_EXPIRED) {
|
||||
/* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
|
||||
returned so we have to work around that in cleanup. */
|
||||
connssl->recv_sspi_close_notify = true;
|
||||
if(!connssl->recv_connection_closed) {
|
||||
connssl->recv_connection_closed = true;
|
||||
BACKEND->recv_sspi_close_notify = true;
|
||||
if(!BACKEND->recv_connection_closed) {
|
||||
BACKEND->recv_connection_closed = true;
|
||||
infof(data, "schannel: server closed the connection\n");
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
|
||||
connssl->encdata_is_incomplete = true;
|
||||
BACKEND->encdata_is_incomplete = true;
|
||||
if(!*err)
|
||||
*err = CURLE_AGAIN;
|
||||
infof(data, "schannel: failed to decrypt data, need more data\n");
|
||||
@ -1383,10 +1385,10 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
|
||||
infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
|
||||
connssl->encdata_offset, connssl->encdata_length);
|
||||
BACKEND->encdata_offset, BACKEND->encdata_length);
|
||||
|
||||
infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
|
||||
connssl->decdata_offset, connssl->decdata_length);
|
||||
BACKEND->decdata_offset, BACKEND->decdata_length);
|
||||
|
||||
cleanup:
|
||||
/* Warning- there is no guarantee the encdata state is valid at this point */
|
||||
@ -1400,13 +1402,13 @@ cleanup:
|
||||
return close_notify. In that case if the connection was closed we assume it
|
||||
was graceful (close_notify) since there doesn't seem to be a way to tell.
|
||||
*/
|
||||
if(len && !connssl->decdata_offset && connssl->recv_connection_closed &&
|
||||
!connssl->recv_sspi_close_notify) {
|
||||
if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed &&
|
||||
!BACKEND->recv_sspi_close_notify) {
|
||||
bool isWin2k = Curl_verify_windows_version(5, 0, PLATFORM_WINNT,
|
||||
VERSION_EQUAL);
|
||||
|
||||
if(isWin2k && sspi_status == SEC_E_OK)
|
||||
connssl->recv_sspi_close_notify = true;
|
||||
BACKEND->recv_sspi_close_notify = true;
|
||||
else {
|
||||
*err = CURLE_RECV_ERROR;
|
||||
infof(data, "schannel: server closed abruptly (missing close_notify)\n");
|
||||
@ -1415,23 +1417,23 @@ cleanup:
|
||||
|
||||
/* Any error other than CURLE_AGAIN is an unrecoverable error. */
|
||||
if(*err && *err != CURLE_AGAIN)
|
||||
connssl->recv_unrecoverable_err = *err;
|
||||
BACKEND->recv_unrecoverable_err = *err;
|
||||
|
||||
size = len < connssl->decdata_offset ? len : connssl->decdata_offset;
|
||||
size = len < BACKEND->decdata_offset ? len : BACKEND->decdata_offset;
|
||||
if(size) {
|
||||
memcpy(buf, connssl->decdata_buffer, size);
|
||||
memmove(connssl->decdata_buffer, connssl->decdata_buffer + size,
|
||||
connssl->decdata_offset - size);
|
||||
connssl->decdata_offset -= size;
|
||||
memcpy(buf, BACKEND->decdata_buffer, size);
|
||||
memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size,
|
||||
BACKEND->decdata_offset - size);
|
||||
BACKEND->decdata_offset -= size;
|
||||
|
||||
infof(data, "schannel: decrypted data returned %zu\n", size);
|
||||
infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
|
||||
connssl->decdata_offset, connssl->decdata_length);
|
||||
BACKEND->decdata_offset, BACKEND->decdata_length);
|
||||
*err = CURLE_OK;
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
if(!*err && !connssl->recv_connection_closed)
|
||||
if(!*err && !BACKEND->recv_connection_closed)
|
||||
*err = CURLE_AGAIN;
|
||||
|
||||
/* It's debatable what to return when !len. We could return whatever error we
|
||||
@ -1469,8 +1471,8 @@ static bool Curl_schannel_data_pending(const struct connectdata *conn,
|
||||
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
if(connssl->use) /* SSL/TLS is in use */
|
||||
return (connssl->decdata_offset > 0 ||
|
||||
(connssl->encdata_offset > 0 && !connssl->encdata_is_incomplete));
|
||||
return (BACKEND->decdata_offset > 0 ||
|
||||
(BACKEND->encdata_offset > 0 && !BACKEND->encdata_is_incomplete));
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
@ -1507,7 +1509,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
|
||||
infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
|
||||
hostname, conn->remote_port);
|
||||
|
||||
if(connssl->cred && connssl->ctxt) {
|
||||
if(BACKEND->cred && BACKEND->ctxt) {
|
||||
SecBufferDesc BuffDesc;
|
||||
SecBuffer Buffer;
|
||||
SECURITY_STATUS sspi_status;
|
||||
@ -1520,7 +1522,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
|
||||
InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
|
||||
InitSecBufferDesc(&BuffDesc, &Buffer, 1);
|
||||
|
||||
sspi_status = s_pSecFn->ApplyControlToken(&connssl->ctxt->ctxt_handle,
|
||||
sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle,
|
||||
&BuffDesc);
|
||||
|
||||
if(sspi_status != SEC_E_OK)
|
||||
@ -1536,18 +1538,18 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
|
||||
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
|
||||
|
||||
sspi_status = s_pSecFn->InitializeSecurityContext(
|
||||
&connssl->cred->cred_handle,
|
||||
&connssl->ctxt->ctxt_handle,
|
||||
&BACKEND->cred->cred_handle,
|
||||
&BACKEND->ctxt->ctxt_handle,
|
||||
host_name,
|
||||
connssl->req_flags,
|
||||
BACKEND->req_flags,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
&connssl->ctxt->ctxt_handle,
|
||||
&BACKEND->ctxt->ctxt_handle,
|
||||
&outbuf_desc,
|
||||
&connssl->ret_flags,
|
||||
&connssl->ctxt->time_stamp);
|
||||
&BACKEND->ret_flags,
|
||||
&BACKEND->ctxt->time_stamp);
|
||||
|
||||
Curl_unicodefree(host_name);
|
||||
|
||||
@ -1566,33 +1568,33 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* free SSPI Schannel API security context handle */
|
||||
if(connssl->ctxt) {
|
||||
if(BACKEND->ctxt) {
|
||||
infof(data, "schannel: clear security context handle\n");
|
||||
s_pSecFn->DeleteSecurityContext(&connssl->ctxt->ctxt_handle);
|
||||
Curl_safefree(connssl->ctxt);
|
||||
s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle);
|
||||
Curl_safefree(BACKEND->ctxt);
|
||||
}
|
||||
|
||||
/* free SSPI Schannel API credential handle */
|
||||
if(connssl->cred) {
|
||||
if(BACKEND->cred) {
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
Curl_schannel_session_free(connssl->cred);
|
||||
Curl_schannel_session_free(BACKEND->cred);
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
connssl->cred = NULL;
|
||||
BACKEND->cred = NULL;
|
||||
}
|
||||
|
||||
/* free internal buffer for received encrypted data */
|
||||
if(connssl->encdata_buffer != NULL) {
|
||||
Curl_safefree(connssl->encdata_buffer);
|
||||
connssl->encdata_length = 0;
|
||||
connssl->encdata_offset = 0;
|
||||
connssl->encdata_is_incomplete = false;
|
||||
if(BACKEND->encdata_buffer != NULL) {
|
||||
Curl_safefree(BACKEND->encdata_buffer);
|
||||
BACKEND->encdata_length = 0;
|
||||
BACKEND->encdata_offset = 0;
|
||||
BACKEND->encdata_is_incomplete = false;
|
||||
}
|
||||
|
||||
/* free internal buffer for received decrypted data */
|
||||
if(connssl->decdata_buffer != NULL) {
|
||||
Curl_safefree(connssl->decdata_buffer);
|
||||
connssl->decdata_length = 0;
|
||||
connssl->decdata_offset = 0;
|
||||
if(BACKEND->decdata_buffer != NULL) {
|
||||
Curl_safefree(BACKEND->decdata_buffer);
|
||||
BACKEND->decdata_length = 0;
|
||||
BACKEND->decdata_offset = 0;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
@ -1646,7 +1648,7 @@ static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
|
||||
conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
|
||||
status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
|
||||
status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
|
||||
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
|
||||
&pCertContextServer);
|
||||
|
||||
@ -1777,7 +1779,7 @@ static void *Curl_schannel_get_internals(struct ssl_connect_data *connssl,
|
||||
CURLINFO info UNUSED_PARAM)
|
||||
{
|
||||
(void)info;
|
||||
return &connssl->ctxt->ctxt_handle;
|
||||
return &BACKEND->ctxt->ctxt_handle;
|
||||
}
|
||||
|
||||
const struct Curl_ssl Curl_ssl_schannel = {
|
||||
|
Loading…
Reference in New Issue
Block a user