aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/curl/lib/vtls
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.ru>2022-04-20 17:40:08 +0300
committerthegeorg <thegeorg@yandex-team.ru>2022-04-20 17:40:08 +0300
commit31ff69685d432e9506ba2cad2e4cb05528021282 (patch)
tree70ed539fcc48dd4d1981fd4785797a11cd7e4006 /contrib/libs/curl/lib/vtls
parent9abb1ba6ed6c2852738c0f69367b9c0bff668676 (diff)
downloadydb-31ff69685d432e9506ba2cad2e4cb05528021282.tar.gz
Update contrib/libs/curl to 7.81.0
ref:47b24ca6f73cd31c101d7e08fb558fb7ddd6b54f
Diffstat (limited to 'contrib/libs/curl/lib/vtls')
-rw-r--r--contrib/libs/curl/lib/vtls/gtls.c34
-rw-r--r--contrib/libs/curl/lib/vtls/gtls.h8
-rw-r--r--contrib/libs/curl/lib/vtls/mbedtls.c53
-rw-r--r--contrib/libs/curl/lib/vtls/mesalink.c91
-rw-r--r--contrib/libs/curl/lib/vtls/nss.c100
-rw-r--r--contrib/libs/curl/lib/vtls/openssl.c180
-rw-r--r--contrib/libs/curl/lib/vtls/openssl.h8
-rw-r--r--contrib/libs/curl/lib/vtls/rustls.c61
-rw-r--r--contrib/libs/curl/lib/vtls/schannel.c397
-rw-r--r--contrib/libs/curl/lib/vtls/schannel_verify.c5
-rw-r--r--contrib/libs/curl/lib/vtls/sectransp.c30
11 files changed, 544 insertions, 423 deletions
diff --git a/contrib/libs/curl/lib/vtls/gtls.c b/contrib/libs/curl/lib/vtls/gtls.c
index 2053fd439d..18864aa4b2 100644
--- a/contrib/libs/curl/lib/vtls/gtls.c
+++ b/contrib/libs/curl/lib/vtls/gtls.c
@@ -497,6 +497,7 @@ gtls_connect_step1(struct Curl_easy *data,
/* use system ca certificate store as fallback */
if(SSL_CONN_CONFIG(verifypeer) &&
!(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
+ /* this ignores errors on purpose */
gnutls_certificate_set_x509_system_trust(backend->cred);
}
#endif
@@ -631,7 +632,10 @@ gtls_connect_step1(struct Curl_easy *data,
cur++;
infof(data, "ALPN, offering %s", ALPN_HTTP_1_1);
- gnutls_alpn_set_protocols(session, protocols, cur, 0);
+ if(gnutls_alpn_set_protocols(session, protocols, cur, 0)) {
+ failf(data, "failed setting ALPN");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
}
if(SSL_SET_OPTION(primary.clientcert)) {
@@ -757,10 +761,10 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
/* if a path wasn't specified, don't pin */
- if(NULL == pinnedpubkey)
+ if(!pinnedpubkey)
return CURLE_OK;
- if(NULL == cert)
+ if(!cert)
return result;
do {
@@ -778,7 +782,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
break; /* failed */
buff1 = malloc(len1);
- if(NULL == buff1)
+ if(!buff1)
break; /* failed */
len2 = len1;
@@ -793,7 +797,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
} while(0);
- if(NULL != key)
+ if(key)
gnutls_pubkey_deinit(key);
Curl_safefree(buff1);
@@ -804,10 +808,11 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
static Curl_recv gtls_recv;
static Curl_send gtls_send;
-static CURLcode
-gtls_connect_step3(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+CURLcode
+Curl_gtls_verifyserver(struct Curl_easy *data,
+ struct connectdata *conn,
+ gnutls_session_t session,
+ int sockindex)
{
unsigned int cert_list_size;
const gnutls_datum_t *chainp;
@@ -819,9 +824,6 @@ gtls_connect_step3(struct Curl_easy *data,
size_t size;
time_t certclock;
const char *ptr;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct ssl_backend_data *backend = connssl->backend;
- gnutls_session_t session = backend->session;
int rc;
gnutls_datum_t proto;
CURLcode result = CURLE_OK;
@@ -1265,8 +1267,6 @@ gtls_connect_step3(struct Curl_easy *data,
}
conn->ssl[sockindex].state = ssl_connection_complete;
- conn->recv[sockindex] = gtls_recv;
- conn->send[sockindex] = gtls_send;
if(SSL_SET_OPTION(primary.sessionid)) {
/* we always unconditionally get the session id here, as even if we
@@ -1351,9 +1351,13 @@ gtls_connect_common(struct Curl_easy *data,
/* Finish connecting once the handshake is done */
if(ssl_connect_1 == connssl->connecting_state) {
- rc = gtls_connect_step3(data, conn, sockindex);
+ struct ssl_backend_data *backend = connssl->backend;
+ gnutls_session_t session = backend->session;
+ rc = Curl_gtls_verifyserver(data, conn, session, sockindex);
if(rc)
return rc;
+ conn->recv[sockindex] = gtls_recv;
+ conn->send[sockindex] = gtls_send;
}
*done = ssl_connect_1 == connssl->connecting_state;
diff --git a/contrib/libs/curl/lib/vtls/gtls.h b/contrib/libs/curl/lib/vtls/gtls.h
index 1a146a3a93..642d5f093a 100644
--- a/contrib/libs/curl/lib/vtls/gtls.h
+++ b/contrib/libs/curl/lib/vtls/gtls.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -27,7 +27,11 @@
#ifdef USE_GNUTLS
#include "urldata.h"
-
+#include <gnutls/gnutls.h>
+CURLcode
+Curl_gtls_verifyserver(struct Curl_easy *data, struct connectdata *conn,
+ gnutls_session_t session,
+ int sockindex);
extern const struct Curl_ssl Curl_ssl_gnutls;
#endif /* USE_GNUTLS */
diff --git a/contrib/libs/curl/lib/vtls/mbedtls.c b/contrib/libs/curl/lib/vtls/mbedtls.c
index 3b08df9662..e177d3990d 100644
--- a/contrib/libs/curl/lib/vtls/mbedtls.c
+++ b/contrib/libs/curl/lib/vtls/mbedtls.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
@@ -270,7 +270,10 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
- const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+ const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
+ const char * const ssl_cafile =
+ /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
+ (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
@@ -316,16 +319,34 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
/* Load the trusted CA */
mbedtls_x509_crt_init(&backend->cacert);
- if(ssl_cafile) {
+ if(ca_info_blob && verifypeer) {
+ /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
+ terminated even when provided the exact length, forcing us to waste
+ extra memory here. */
+ unsigned char *newblob = malloc(ca_info_blob->len + 1);
+ if(!newblob)
+ return CURLE_OUT_OF_MEMORY;
+ memcpy(newblob, ca_info_blob->data, ca_info_blob->len);
+ newblob[ca_info_blob->len] = 0; /* null terminate */
+ ret = mbedtls_x509_crt_parse(&backend->cacert, newblob,
+ ca_info_blob->len + 1);
+ free(newblob);
+ if(ret<0) {
+ mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+ failf(data, "Error importing ca cert blob - mbedTLS: (-0x%04X) %s",
+ -ret, errorbuf);
+ return ret;
+ }
+ }
+
+ if(ssl_cafile && verifypeer) {
ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile);
if(ret<0) {
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
ssl_cafile, -ret, errorbuf);
-
- if(verifypeer)
- return CURLE_SSL_CACERT_BADFILE;
+ return CURLE_SSL_CACERT_BADFILE;
}
}
@@ -358,10 +379,17 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
if(ssl_cert_blob) {
- const unsigned char *blob_data =
- (const unsigned char *)ssl_cert_blob->data;
- ret = mbedtls_x509_crt_parse(&backend->clicert, blob_data,
+ /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
+ terminated even when provided the exact length, forcing us to waste
+ extra memory here. */
+ unsigned char *newblob = malloc(ssl_cert_blob->len + 1);
+ if(!newblob)
+ return CURLE_OUT_OF_MEMORY;
+ memcpy(newblob, ssl_cert_blob->data, ssl_cert_blob->len);
+ newblob[ssl_cert_blob->len] = 0; /* null terminate */
+ ret = mbedtls_x509_crt_parse(&backend->clicert, newblob,
ssl_cert_blob->len);
+ free(newblob);
if(ret) {
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
@@ -671,7 +699,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
mbedtls_x509_crt *p = NULL;
unsigned char *pubkey = NULL;
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER == 0x03000000
if(!peercert || !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p) ||
!peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len)) {
#else
@@ -698,7 +726,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
needs a non-const key, for now.
https://github.com/ARMmbed/mbedtls/issues/396 */
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER == 0x03000000
if(mbedtls_x509_crt_parse_der(p,
peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p),
peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len))) {
@@ -710,7 +738,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
goto pinnedpubkey_error;
}
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER == 0x03000000
size = mbedtls_pk_write_pubkey_der(&p->MBEDTLS_PRIVATE(pk), pubkey,
PUB_DER_MAX_BYTES);
#else
@@ -1154,6 +1182,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
{ CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */
SSLSUPP_CA_PATH |
+ SSLSUPP_CAINFO_BLOB |
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_SSL_CTX,
diff --git a/contrib/libs/curl/lib/vtls/mesalink.c b/contrib/libs/curl/lib/vtls/mesalink.c
index 0a1dea3ac0..35a916586e 100644
--- a/contrib/libs/curl/lib/vtls/mesalink.c
+++ b/contrib/libs/curl/lib/vtls/mesalink.c
@@ -68,8 +68,6 @@ struct ssl_backend_data
SSL *handle;
};
-#define BACKEND connssl->backend
-
static Curl_recv mesalink_recv;
static Curl_send mesalink_send;
@@ -100,9 +98,9 @@ mesalink_connect_step1(struct Curl_easy *data,
#endif
const char * const hostname = SSL_HOST_NAME();
size_t hostname_len = strlen(hostname);
-
SSL_METHOD *req_method = NULL;
curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
if(connssl->state == ssl_connection_complete)
return CURLE_OK;
@@ -139,22 +137,22 @@ mesalink_connect_step1(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
- if(BACKEND->ctx)
- SSL_CTX_free(BACKEND->ctx);
- BACKEND->ctx = SSL_CTX_new(req_method);
+ if(backend->ctx)
+ SSL_CTX_free(backend->ctx);
+ backend->ctx = SSL_CTX_new(req_method);
- if(!BACKEND->ctx) {
+ if(!backend->ctx) {
failf(data, "SSL: couldn't create a context!");
return CURLE_OUT_OF_MEMORY;
}
SSL_CTX_set_verify(
- BACKEND->ctx, SSL_CONN_CONFIG(verifypeer) ?
+ backend->ctx, SSL_CONN_CONFIG(verifypeer) ?
SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath)) {
- if(!SSL_CTX_load_verify_locations(BACKEND->ctx, SSL_CONN_CONFIG(CAfile),
- SSL_CONN_CONFIG(CApath))) {
+ if(!SSL_CTX_load_verify_locations(backend->ctx, SSL_CONN_CONFIG(CAfile),
+ SSL_CONN_CONFIG(CApath))) {
if(SSL_CONN_CONFIG(verifypeer)) {
failf(data,
"error setting certificate verify locations: "
@@ -181,7 +179,7 @@ mesalink_connect_step1(struct Curl_easy *data,
if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) {
int file_type = do_file_type(SSL_SET_OPTION(cert_type));
- if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx,
+ if(SSL_CTX_use_certificate_chain_file(backend->ctx,
SSL_SET_OPTION(primary.clientcert),
file_type) != 1) {
failf(data, "unable to use client certificate (no key or wrong pass"
@@ -190,8 +188,8 @@ mesalink_connect_step1(struct Curl_easy *data,
}
file_type = do_file_type(SSL_SET_OPTION(key_type));
- if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
- file_type) != 1) {
+ 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;
}
@@ -204,7 +202,7 @@ mesalink_connect_step1(struct Curl_easy *data,
ciphers = SSL_CONN_CONFIG(cipher_list);
if(ciphers) {
#ifdef MESALINK_HAVE_CIPHER
- if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
+ if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
failf(data, "failed setting cipher list: %s", ciphers);
return CURLE_SSL_CIPHER;
}
@@ -212,10 +210,10 @@ mesalink_connect_step1(struct Curl_easy *data,
infof(data, "Cipher selection: %s", ciphers);
}
- if(BACKEND->handle)
- SSL_free(BACKEND->handle);
- BACKEND->handle = SSL_new(BACKEND->ctx);
- if(!BACKEND->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;
}
@@ -227,7 +225,7 @@ mesalink_connect_step1(struct Curl_easy *data,
#endif
) {
/* hostname is not a valid IP address */
- if(SSL_set_tlsext_host_name(BACKEND->handle, hostname) != SSL_SUCCESS) {
+ if(SSL_set_tlsext_host_name(backend->handle, hostname) != SSL_SUCCESS) {
failf(data,
"WARNING: failed to configure server name indication (SNI) "
"TLS extension\n");
@@ -244,7 +242,7 @@ mesalink_connect_step1(struct Curl_easy *data,
|| strncmp(hostname, "[::1]", 5) == 0
#endif
) {
- SSL_set_tlsext_host_name(BACKEND->handle, "localhost");
+ SSL_set_tlsext_host_name(backend->handle, "localhost");
}
else
#endif
@@ -264,12 +262,12 @@ mesalink_connect_step1(struct Curl_easy *data,
SSL_IS_PROXY() ? TRUE : FALSE,
&ssl_sessionid, NULL, sockindex)) {
/* we got a session id, use it! */
- if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
+ if(!SSL_set_session(backend->handle, ssl_sessionid)) {
Curl_ssl_sessionid_unlock(data);
failf(
data,
"SSL: SSL_set_session failed: %s",
- ERR_error_string(SSL_get_error(BACKEND->handle, 0), error_buffer));
+ ERR_error_string(SSL_get_error(backend->handle, 0), error_buffer));
return CURLE_SSL_CONNECT_ERROR;
}
/* Informational message */
@@ -279,7 +277,7 @@ mesalink_connect_step1(struct Curl_easy *data,
}
#endif /* MESALINK_HAVE_SESSION */
- if(SSL_set_fd(BACKEND->handle, (int)sockfd) != SSL_SUCCESS) {
+ if(SSL_set_fd(backend->handle, (int)sockfd) != SSL_SUCCESS) {
failf(data, "SSL: SSL_set_fd failed");
return CURLE_SSL_CONNECT_ERROR;
}
@@ -294,13 +292,14 @@ mesalink_connect_step2(struct Curl_easy *data,
{
int ret = -1;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
conn->recv[sockindex] = mesalink_recv;
conn->send[sockindex] = mesalink_send;
- ret = SSL_connect(BACKEND->handle);
+ ret = SSL_connect(backend->handle);
if(ret != SSL_SUCCESS) {
- int detail = SSL_get_error(BACKEND->handle, ret);
+ int detail = SSL_get_error(backend->handle, ret);
if(SSL_ERROR_WANT_CONNECT == detail || SSL_ERROR_WANT_READ == detail) {
connssl->connecting_state = ssl_connect_2_reading;
@@ -327,8 +326,8 @@ mesalink_connect_step2(struct Curl_easy *data,
connssl->connecting_state = ssl_connect_3;
infof(data,
"SSL connection using %s / %s",
- SSL_get_version(BACKEND->handle),
- SSL_get_cipher_name(BACKEND->handle));
+ SSL_get_version(backend->handle),
+ SSL_get_cipher_name(backend->handle));
return CURLE_OK;
}
@@ -347,8 +346,9 @@ mesalink_connect_step3(struct connectdata *conn, int sockindex)
SSL_SESSION *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
+ struct ssl_backend_data *backend = connssl->backend;
- our_ssl_sessionid = SSL_get_session(BACKEND->handle);
+ our_ssl_sessionid = SSL_get_session(backend->handle);
Curl_ssl_sessionid_lock(data);
incache =
@@ -387,12 +387,13 @@ mesalink_send(struct Curl_easy *data, int sockindex, const void *mem,
{
struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
char error_buffer[MESALINK_MAX_ERROR_SZ];
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
- int rc = SSL_write(BACKEND->handle, mem, memlen);
+ int rc = SSL_write(backend->handle, mem, memlen);
if(rc < 0) {
- int err = SSL_get_error(BACKEND->handle, rc);
+ int err = SSL_get_error(backend->handle, rc);
switch(err) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
@@ -415,17 +416,18 @@ static void
mesalink_close(struct Curl_easy *data, struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
(void) data;
- if(BACKEND->handle) {
- (void)SSL_shutdown(BACKEND->handle);
- SSL_free(BACKEND->handle);
- BACKEND->handle = NULL;
+ if(backend->handle) {
+ (void)SSL_shutdown(backend->handle);
+ SSL_free(backend->handle);
+ backend->handle = NULL;
}
- if(BACKEND->ctx) {
- SSL_CTX_free(BACKEND->ctx);
- BACKEND->ctx = NULL;
+ if(backend->ctx) {
+ SSL_CTX_free(backend->ctx);
+ backend->ctx = NULL;
}
}
@@ -435,12 +437,13 @@ mesalink_recv(struct Curl_easy *data, int num, char *buf, size_t buffersize,
{
struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[num];
+ struct ssl_backend_data *backend = connssl->backend;
char error_buffer[MESALINK_MAX_ERROR_SZ];
int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
- int nread = SSL_read(BACKEND->handle, buf, buffsize);
+ int nread = SSL_read(backend->handle, buf, buffsize);
if(nread <= 0) {
- int err = SSL_get_error(BACKEND->handle, nread);
+ int err = SSL_get_error(backend->handle, nread);
switch(err) {
case SSL_ERROR_ZERO_RETURN: /* no more data */
@@ -485,12 +488,13 @@ mesalink_shutdown(struct Curl_easy *data,
{
int retval = 0;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
(void) data;
- if(BACKEND->handle) {
- SSL_free(BACKEND->handle);
- BACKEND->handle = NULL;
+ if(backend->handle) {
+ SSL_free(backend->handle);
+ backend->handle = NULL;
}
return retval;
}
@@ -636,8 +640,9 @@ static void *
mesalink_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
+ struct ssl_backend_data *backend = connssl->backend;
(void)info;
- return BACKEND->handle;
+ return backend->handle;
}
const struct Curl_ssl Curl_ssl_mesalink = {
diff --git a/contrib/libs/curl/lib/vtls/nss.c b/contrib/libs/curl/lib/vtls/nss.c
index 1897b9ab1d..2b44f05126 100644
--- a/contrib/libs/curl/lib/vtls/nss.c
+++ b/contrib/libs/curl/lib/vtls/nss.c
@@ -304,13 +304,14 @@ static char *nss_sslver_to_name(PRUint16 nssver)
}
}
-static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
- char *cipher_list)
+/* the longest cipher name this supports */
+#define MAX_CIPHER_LENGTH 128
+
+static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc *model,
+ const char *cipher_list)
{
unsigned int i;
- PRBool cipher_state[NUM_OF_CIPHERS];
- PRBool found;
- char *cipher;
+ const char *cipher;
/* use accessors to avoid dynamic linking issues after an update of NSS */
const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers();
@@ -326,51 +327,52 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE);
}
- /* Set every entry in our list to false */
- for(i = 0; i < NUM_OF_CIPHERS; i++) {
- cipher_state[i] = PR_FALSE;
- }
-
cipher = cipher_list;
- while(cipher_list && (cipher_list[0])) {
+ while(cipher && cipher[0]) {
+ const char *end;
+ char name[MAX_CIPHER_LENGTH + 1];
+ size_t len;
+ bool found = FALSE;
while((*cipher) && (ISSPACE(*cipher)))
++cipher;
- cipher_list = strpbrk(cipher, ":, ");
- if(cipher_list) {
- *cipher_list++ = '\0';
- }
-
- found = PR_FALSE;
-
- for(i = 0; i<NUM_OF_CIPHERS; i++) {
- if(strcasecompare(cipher, cipherlist[i].name)) {
- cipher_state[i] = PR_TRUE;
- found = PR_TRUE;
- break;
- }
- }
+ end = strpbrk(cipher, ":, ");
+ if(end)
+ len = end - cipher;
+ else
+ len = strlen(cipher);
- if(found == PR_FALSE) {
- failf(data, "Unknown cipher in list: %s", cipher);
+ if(len > MAX_CIPHER_LENGTH) {
+ failf(data, "Bad cipher list");
return SECFailure;
}
-
- if(cipher_list) {
- cipher = cipher_list;
+ else if(len) {
+ memcpy(name, cipher, len);
+ name[len] = 0;
+
+ for(i = 0; i<NUM_OF_CIPHERS; i++) {
+ if(strcasecompare(name, cipherlist[i].name)) {
+ /* Enable the selected cipher */
+ if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) !=
+ SECSuccess) {
+ failf(data, "cipher-suite not supported by NSS: %s", name);
+ return SECFailure;
+ }
+ found = TRUE;
+ break;
+ }
+ }
}
- }
- /* Finally actually enable the selected ciphers */
- for(i = 0; i<NUM_OF_CIPHERS; i++) {
- if(!cipher_state[i])
- continue;
-
- if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) != SECSuccess) {
- failf(data, "cipher-suite not supported by NSS: %s", cipherlist[i].name);
+ if(!found && len) {
+ failf(data, "Unknown cipher: %s", name);
return SECFailure;
}
+ if(end)
+ cipher = ++end;
+ else
+ break;
}
return SECSuccess;
@@ -782,7 +784,7 @@ static char *nss_get_password(PK11SlotInfo *slot, PRBool retry, void *arg)
{
(void)slot; /* unused */
- if(retry || NULL == arg)
+ if(retry || !arg)
return NULL;
else
return (char *)PORT_Strdup((char *)arg);
@@ -1168,7 +1170,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
struct SECKEYPrivateKeyStr *key;
PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname);
- if(NULL == slot) {
+ if(!slot) {
failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
return SECFailure;
}
@@ -1182,7 +1184,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
SECITEM_FreeItem(&cert_der, PR_FALSE);
- if(NULL == cert) {
+ if(!cert) {
failf(data, "NSS: client certificate from file not found");
PK11_FreeSlot(slot);
return SECFailure;
@@ -1190,7 +1192,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
PK11_FreeSlot(slot);
- if(NULL == key) {
+ if(!key) {
failf(data, "NSS: private key from file not found");
CERT_DestroyCertificate(cert);
return SECFailure;
@@ -1207,9 +1209,9 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
/* use the default NSS hook */
if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
pRetCert, pRetKey)
- || NULL == *pRetCert) {
+ || !*pRetCert) {
- if(NULL == nickname)
+ if(!nickname)
failf(data, "NSS: client certificate not found (nickname not "
"specified)");
else
@@ -1220,7 +1222,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
/* get certificate nickname if any */
nickname = (*pRetCert)->nickname;
- if(NULL == nickname)
+ if(!nickname)
nickname = "[unknown]";
if(!strncmp(nickname, pem_slotname, sizeof(pem_slotname) - 1U)) {
@@ -1229,7 +1231,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
return SECFailure;
}
- if(NULL == *pRetKey) {
+ if(!*pRetKey) {
failf(data, "NSS: private key not found for certificate: %s", nickname);
return SECFailure;
}
@@ -1344,7 +1346,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
PRErrorCode err;
const char *err_name;
- if(nss_context != NULL)
+ if(nss_context)
return CURLE_OK;
memset((void *) &initparams, '\0', sizeof(initparams));
@@ -1360,7 +1362,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
free(certpath);
- if(nss_context != NULL)
+ if(nss_context)
return CURLE_OK;
err = PR_GetError();
@@ -1372,7 +1374,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
| NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
| NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
- if(nss_context != NULL)
+ if(nss_context)
return CURLE_OK;
err = PR_GetError();
diff --git a/contrib/libs/curl/lib/vtls/openssl.c b/contrib/libs/curl/lib/vtls/openssl.c
index a1baef9c3f..8c0f946dd5 100644
--- a/contrib/libs/curl/lib/vtls/openssl.c
+++ b/contrib/libs/curl/lib/vtls/openssl.c
@@ -171,6 +171,21 @@
#define OPENSSL_load_builtin_modules(x)
#endif
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+#define HAVE_EVP_PKEY_GET_PARAMS 1
+#else
+#define SSL_get1_peer_certificate SSL_get_peer_certificate
+#endif
+
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+#error #include <openssl/core_names.h>
+#define DECLARE_PKEY_PARAM_BIGNUM(name) BIGNUM *name = NULL
+#define FREE_PKEY_PARAM_BIGNUM(name) BN_clear_free(name)
+#else
+#define DECLARE_PKEY_PARAM_BIGNUM(name) const BIGNUM *name
+#define FREE_PKEY_PARAM_BIGNUM(name)
+#endif
+
/*
* Whether SSL_CTX_set_keylog_callback is available.
* OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287
@@ -231,6 +246,13 @@
#define HAVE_RANDOM_INIT_BY_DEFAULT 1
#endif
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+ !(defined(LIBRESSL_VERSION_NUMBER) && \
+ LIBRESSL_VERSION_NUMBER < 0x2070100fL) && \
+ !defined(OPENSSL_IS_BORINGSSL)
+#define HAVE_OPENSSL_VERSION
+#endif
+
struct ssl_backend_data {
struct Curl_easy *logger; /* transfer handle to pass trace logs to, only
using sockindex 0 */
@@ -1099,7 +1121,8 @@ int cert_stuff(struct Curl_easy *data,
EVP_PKEY_free(pktmp);
}
-#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL)
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL) && \
+ !defined(OPENSSL_NO_DEPRECATED_3_0)
{
/* If RSA is used, don't check the private key if its flags indicate
* it doesn't support it. */
@@ -1412,6 +1435,12 @@ static void ossl_closeone(struct Curl_easy *data,
if(backend->handle) {
char buf[32];
set_logger(conn, data);
+ /*
+ * The conn->sock[0] socket is passed to openssl with SSL_set_fd(). Make
+ * sure the socket is not closed before calling OpenSSL functions that
+ * will use it.
+ */
+ DEBUGASSERT(conn->sock[FIRSTSOCKET] != CURL_SOCKET_BAD);
/* Maybe the server has already sent a close notify alert.
Read it to avoid an RST on the TCP connection. */
@@ -1650,9 +1679,10 @@ static bool subj_alt_hostcheck(struct Curl_easy *data,
hostname. In this case, the iPAddress subjectAltName must be present
in the certificate and must exactly match the IP in the URI.
+ This function is now used from ngtcp2 (QUIC) as well.
*/
-static CURLcode verifyhost(struct Curl_easy *data, struct connectdata *conn,
- X509 *server_cert)
+CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
+ X509 *server_cert)
{
bool matched = FALSE;
int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
@@ -1937,7 +1967,7 @@ static CURLcode verifystatus(struct Curl_easy *data,
}
/* Compute the certificate's ID */
- cert = SSL_get_peer_certificate(backend->handle);
+ cert = SSL_get1_peer_certificate(backend->handle);
if(!cert) {
failf(data, "Error getting peer certificate");
result = CURLE_SSL_INVALIDCERTSTATUS;
@@ -3466,10 +3496,7 @@ static void pubkey_show(struct Curl_easy *data,
int num,
const char *type,
const char *name,
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
- const
-#endif
- BIGNUM *bn)
+ const BIGNUM *bn)
{
char *ptr;
char namebuf[32];
@@ -3534,12 +3561,6 @@ typedef size_t numcert_t;
typedef int numcert_t;
#endif
-#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
-#define OSSL3_CONST const
-#else
-#define OSSL3_CONST
-#endif
-
static CURLcode get_cert_chain(struct Curl_easy *data,
struct ssl_connect_data *connssl)
{
@@ -3563,6 +3584,9 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
}
mem = BIO_new(BIO_s_mem());
+ if(!mem) {
+ return CURLE_OUT_OF_MEMORY;
+ }
for(i = 0; i < (int)numcerts; i++) {
ASN1_INTEGER *num;
@@ -3647,92 +3671,115 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
switch(pktype) {
case EVP_PKEY_RSA:
{
- OSSL3_CONST RSA *rsa;
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ RSA *rsa;
#ifdef HAVE_OPAQUE_EVP_PKEY
rsa = EVP_PKEY_get0_RSA(pubkey);
#else
rsa = pubkey->pkey.rsa;
-#endif
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
{
- const BIGNUM *n;
- const BIGNUM *e;
-
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(n);
+ DECLARE_PKEY_PARAM_BIGNUM(e);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e);
+#else
RSA_get0_key(rsa, &n, &e, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
BIO_printf(mem, "%d", BN_num_bits(n));
+#else
+ BIO_printf(mem, "%d", BN_num_bits(rsa->n));
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
push_certinfo("RSA Public Key", i);
print_pubkey_BN(rsa, n, i);
print_pubkey_BN(rsa, e, i);
+ FREE_PKEY_PARAM_BIGNUM(n);
+ FREE_PKEY_PARAM_BIGNUM(e);
}
-#else
- BIO_printf(mem, "%d", BN_num_bits(rsa->n));
- push_certinfo("RSA Public Key", i);
- print_pubkey_BN(rsa, n, i);
- print_pubkey_BN(rsa, e, i);
-#endif
break;
}
case EVP_PKEY_DSA:
{
#ifndef OPENSSL_NO_DSA
- OSSL3_CONST DSA *dsa;
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ DSA *dsa;
#ifdef HAVE_OPAQUE_EVP_PKEY
dsa = EVP_PKEY_get0_DSA(pubkey);
#else
dsa = pubkey->pkey.dsa;
-#endif
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
{
- const BIGNUM *p;
- const BIGNUM *q;
- const BIGNUM *g;
- const BIGNUM *pub_key;
-
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(p);
+ DECLARE_PKEY_PARAM_BIGNUM(q);
+ DECLARE_PKEY_PARAM_BIGNUM(g);
+ DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
DSA_get0_pqg(dsa, &p, &q, &g);
DSA_get0_key(dsa, &pub_key, NULL);
-
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
print_pubkey_BN(dsa, p, i);
print_pubkey_BN(dsa, q, i);
print_pubkey_BN(dsa, g, i);
print_pubkey_BN(dsa, pub_key, i);
+ FREE_PKEY_PARAM_BIGNUM(p);
+ FREE_PKEY_PARAM_BIGNUM(q);
+ FREE_PKEY_PARAM_BIGNUM(g);
+ FREE_PKEY_PARAM_BIGNUM(pub_key);
}
-#else
- print_pubkey_BN(dsa, p, i);
- print_pubkey_BN(dsa, q, i);
- print_pubkey_BN(dsa, g, i);
- print_pubkey_BN(dsa, pub_key, i);
-#endif
#endif /* !OPENSSL_NO_DSA */
break;
}
case EVP_PKEY_DH:
{
- OSSL3_CONST DH *dh;
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ DH *dh;
#ifdef HAVE_OPAQUE_EVP_PKEY
dh = EVP_PKEY_get0_DH(pubkey);
#else
dh = pubkey->pkey.dh;
-#endif
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
{
- const BIGNUM *p;
- const BIGNUM *q;
- const BIGNUM *g;
- const BIGNUM *pub_key;
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(p);
+ DECLARE_PKEY_PARAM_BIGNUM(q);
+ DECLARE_PKEY_PARAM_BIGNUM(g);
+ DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
DH_get0_pqg(dh, &p, &q, &g);
DH_get0_key(dh, &pub_key, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
print_pubkey_BN(dh, p, i);
print_pubkey_BN(dh, q, i);
print_pubkey_BN(dh, g, i);
+#else
+ print_pubkey_BN(dh, p, i);
+ print_pubkey_BN(dh, g, i);
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
print_pubkey_BN(dh, pub_key, i);
+ FREE_PKEY_PARAM_BIGNUM(p);
+ FREE_PKEY_PARAM_BIGNUM(q);
+ FREE_PKEY_PARAM_BIGNUM(g);
+ FREE_PKEY_PARAM_BIGNUM(pub_key);
}
-#else
- print_pubkey_BN(dh, p, i);
- print_pubkey_BN(dh, g, i);
- print_pubkey_BN(dh, pub_key, i);
-#endif
break;
}
}
@@ -3836,11 +3883,20 @@ static CURLcode servercert(struct Curl_easy *data,
BIO *mem = BIO_new(BIO_s_mem());
struct ssl_backend_data *backend = connssl->backend;
+ if(!mem) {
+ failf(data,
+ "BIO_new return NULL, " OSSL_PACKAGE
+ " error %s",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)) );
+ return CURLE_OUT_OF_MEMORY;
+ }
+
if(data->set.ssl.certinfo)
/* we've been asked to gather certificate info! */
(void)get_cert_chain(data, connssl);
- backend->server_cert = SSL_get_peer_certificate(backend->handle);
+ backend->server_cert = SSL_get1_peer_certificate(backend->handle);
if(!backend->server_cert) {
BIO_free(mem);
if(!strict)
@@ -3874,7 +3930,7 @@ static CURLcode servercert(struct Curl_easy *data,
BIO_free(mem);
if(SSL_CONN_CONFIG(verifyhost)) {
- result = verifyhost(data, conn, backend->server_cert);
+ result = Curl_ossl_verifyhost(data, conn, backend->server_cert);
if(result) {
X509_free(backend->server_cert);
backend->server_cert = NULL;
@@ -4354,13 +4410,7 @@ static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
static size_t ossl_version(char *buffer, size_t size)
{
#ifdef LIBRESSL_VERSION_NUMBER
-#if LIBRESSL_VERSION_NUMBER < 0x2070100fL
- return msnprintf(buffer, size, "%s/%lx.%lx.%lx",
- OSSL_PACKAGE,
- (LIBRESSL_VERSION_NUMBER>>28)&0xf,
- (LIBRESSL_VERSION_NUMBER>>20)&0xff,
- (LIBRESSL_VERSION_NUMBER>>12)&0xff);
-#else /* OpenSSL_version() first appeared in LibreSSL 2.7.1 */
+#ifdef HAVE_OPENSSL_VERSION
char *p;
int count;
const char *ver = OpenSSL_version(OPENSSL_VERSION);
@@ -4374,6 +4424,12 @@ static size_t ossl_version(char *buffer, size_t size)
*p = '_';
}
return count;
+#else
+ return msnprintf(buffer, size, "%s/%lx.%lx.%lx",
+ OSSL_PACKAGE,
+ (LIBRESSL_VERSION_NUMBER>>28)&0xf,
+ (LIBRESSL_VERSION_NUMBER>>20)&0xff,
+ (LIBRESSL_VERSION_NUMBER>>12)&0xff);
#endif
#elif defined(OPENSSL_IS_BORINGSSL)
return msnprintf(buffer, size, OSSL_PACKAGE);
diff --git a/contrib/libs/curl/lib/vtls/openssl.h b/contrib/libs/curl/lib/vtls/openssl.h
index 2f6e1b2db8..28058453c0 100644
--- a/contrib/libs/curl/lib/vtls/openssl.h
+++ b/contrib/libs/curl/lib/vtls/openssl.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -26,11 +26,15 @@
#ifdef USE_OPENSSL
/*
- * This header should only be needed to get included by vtls.c and openssl.c
+ * This header should only be needed to get included by vtls.c, openssl.c
+ * and ngtcp2.c
*/
+#include <openssl/x509v3.h>
#include "urldata.h"
+CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
+ X509 *server_cert);
extern const struct Curl_ssl Curl_ssl_openssl;
#endif /* USE_OPENSSL */
diff --git a/contrib/libs/curl/lib/vtls/rustls.c b/contrib/libs/curl/lib/vtls/rustls.c
index 29bb4259a4..6dbb1ef3cd 100644
--- a/contrib/libs/curl/lib/vtls/rustls.c
+++ b/contrib/libs/curl/lib/vtls/rustls.c
@@ -27,7 +27,7 @@
#include "curl_printf.h"
#include <errno.h>
-#error #include <crustls.h>
+#include <rustls.h>
#include "inet_pton.h"
#include "urldata.h"
@@ -138,11 +138,6 @@ cr_recv(struct Curl_easy *data, int sockindex,
*err = CURLE_READ_ERROR;
return -1;
}
- else if(tls_bytes_read == 0) {
- failf(data, "connection closed without TLS close_notify alert");
- *err = CURLE_READ_ERROR;
- return -1;
- }
infof(data, "cr_recv read %ld bytes from the network", tls_bytes_read);
@@ -161,22 +156,21 @@ cr_recv(struct Curl_easy *data, int sockindex,
(uint8_t *)plainbuf + plain_bytes_copied,
plainlen - plain_bytes_copied,
&n);
- if(rresult == RUSTLS_RESULT_ALERT_CLOSE_NOTIFY) {
- *err = CURLE_OK;
- return 0;
+ if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) {
+ infof(data, "cr_recv got PLAINTEXT_EMPTY. will try again later.");
+ backend->data_pending = FALSE;
+ break;
}
else if(rresult != RUSTLS_RESULT_OK) {
- failf(data, "error in rustls_connection_read");
+ /* n always equals 0 in this case, don't need to check it */
+ failf(data, "error in rustls_connection_read: %d", rresult);
*err = CURLE_READ_ERROR;
return -1;
}
else if(n == 0) {
- /* rustls returns 0 from connection_read to mean "all currently
- available data has been read." If we bring in more ciphertext with
- read_tls, more plaintext will become available. So don't tell curl
- this is an EOF. Instead, say "come back later." */
- infof(data, "cr_recv got 0 bytes of plaintext");
- backend->data_pending = FALSE;
+ /* n == 0 indicates clean EOF, but we may have read some other
+ plaintext bytes before we reached this. Break out of the loop
+ so we can figure out whether to return success or EOF. */
break;
}
else {
@@ -185,15 +179,23 @@ cr_recv(struct Curl_easy *data, int sockindex,
}
}
- /* If we wrote out 0 plaintext bytes, it might just mean we haven't yet
- read a full TLS record. Return CURLE_AGAIN so curl doesn't treat this
- as EOF. */
- if(plain_bytes_copied == 0) {
+ if(plain_bytes_copied) {
+ *err = CURLE_OK;
+ return plain_bytes_copied;
+ }
+
+ /* If we wrote out 0 plaintext bytes, that means either we hit a clean EOF,
+ OR we got a RUSTLS_RESULT_PLAINTEXT_EMPTY.
+ If the latter, return CURLE_AGAIN so curl doesn't treat this as EOF. */
+ if(!backend->data_pending) {
*err = CURLE_AGAIN;
return -1;
}
- return plain_bytes_copied;
+ /* Zero bytes read, and no RUSTLS_RESULT_PLAINTEXT_EMPTY, means the TCP
+ connection was cleanly closed (with a close_notify alert). */
+ *err = CURLE_OK;
+ return 0;
}
/*
@@ -309,10 +311,10 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
config_builder = rustls_client_config_builder_new();
#ifdef USE_HTTP2
infof(data, "offering ALPN for HTTP/1.1 and HTTP/2");
- rustls_client_config_builder_set_protocols(config_builder, alpn, 2);
+ rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 2);
#else
infof(data, "offering ALPN for HTTP/1.1 only");
- rustls_client_config_builder_set_protocols(config_builder, alpn, 1);
+ rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 1);
#endif
if(!verifypeer) {
rustls_client_config_builder_dangerous_set_certificate_verifier(
@@ -358,7 +360,7 @@ cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn,
size_t len = 0;
rustls_connection_get_alpn_protocol(rconn, &protocol, &len);
- if(NULL == protocol) {
+ if(!protocol) {
infof(data, "ALPN, server did not agree to a protocol");
return;
}
@@ -414,9 +416,6 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
/*
* Connection has been established according to rustls. Set send/recv
* handlers, and update the state machine.
- * This check has to come last because is_handshaking starts out false,
- * then becomes true when we first write data, then becomes false again
- * once the handshake is done.
*/
if(!rustls_connection_is_handshaking(rconn)) {
infof(data, "Done handshaking");
@@ -543,6 +542,12 @@ cr_close(struct Curl_easy *data, struct connectdata *conn,
}
}
+static size_t cr_version(char *buffer, size_t size)
+{
+ struct rustls_str ver = rustls_version();
+ return msnprintf(buffer, size, "%.*s", (int)ver.len, ver.data);
+}
+
const struct Curl_ssl Curl_ssl_rustls = {
{ CURLSSLBACKEND_RUSTLS, "rustls" },
SSLSUPP_TLS13_CIPHERSUITES, /* supports */
@@ -550,7 +555,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
Curl_none_init, /* init */
Curl_none_cleanup, /* cleanup */
- rustls_version, /* version */
+ cr_version, /* version */
Curl_none_check_cxn, /* check_cxn */
Curl_none_shutdown, /* shutdown */
cr_data_pending, /* data_pending */
diff --git a/contrib/libs/curl/lib/vtls/schannel.c b/contrib/libs/curl/lib/vtls/schannel.c
index 44c59e7796..0a8e60610d 100644
--- a/contrib/libs/curl/lib/vtls/schannel.c
+++ b/contrib/libs/curl/lib/vtls/schannel.c
@@ -147,8 +147,6 @@
#define ALG_CLASS_DHASH ALG_CLASS_HASH
#endif
-#define BACKEND connssl->backend
-
static Curl_recv schannel_recv;
static Curl_send schannel_send;
@@ -423,6 +421,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
PCCERT_CONTEXT client_certs[1] = { NULL };
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
+ struct ssl_backend_data *backend = connssl->backend;
/* setup Schannel API options */
memset(&schannel_cred, 0, sizeof(schannel_cred));
@@ -430,7 +429,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
if(conn->ssl_config.verifypeer) {
#ifdef HAS_MANUAL_VERIFY_API
- if(BACKEND->use_manual_cred_validation)
+ if(backend->use_manual_cred_validation)
schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION;
else
#endif
@@ -503,7 +502,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
if(SSL_CONN_CONFIG(cipher_list)) {
result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list),
- BACKEND->algIds);
+ backend->algIds);
if(CURLE_OK != result) {
failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
return result;
@@ -600,7 +599,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
datablob.pbData = (BYTE*)certdata;
datablob.cbData = (DWORD)certsize;
- if(data->set.ssl.key_passwd != NULL)
+ if(data->set.ssl.key_passwd)
pwd_len = strlen(data->set.ssl.key_passwd);
pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1));
if(pszPassword) {
@@ -704,9 +703,9 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
#endif
/* allocate memory for the re-usable credential handle */
- BACKEND->cred = (struct Curl_schannel_cred *)
+ backend->cred = (struct Curl_schannel_cred *)
calloc(1, sizeof(struct Curl_schannel_cred));
- if(!BACKEND->cred) {
+ if(!backend->cred) {
failf(data, "schannel: unable to allocate memory");
if(client_certs[0])
@@ -714,14 +713,14 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
}
- BACKEND->cred->refcount = 1;
+ backend->cred->refcount = 1;
sspi_status =
s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
SECPKG_CRED_OUTBOUND, NULL,
&schannel_cred, NULL, NULL,
- &BACKEND->cred->cred_handle,
- &BACKEND->cred->time_stamp);
+ &backend->cred->cred_handle,
+ &backend->cred->time_stamp);
if(client_certs[0])
CertFreeCertificateContext(client_certs[0]);
@@ -730,7 +729,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
char buffer[STRERROR_LEN];
failf(data, "schannel: AcquireCredentialsHandle failed: %s",
Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
- Curl_safefree(BACKEND->cred);
+ Curl_safefree(backend->cred);
switch(sspi_status) {
case SEC_E_INSUFFICIENT_MEMORY:
return CURLE_OUT_OF_MEMORY;
@@ -769,12 +768,13 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
TCHAR *host_name;
CURLcode result;
char * const hostname = SSL_HOST_NAME();
+ struct ssl_backend_data *backend = connssl->backend;
DEBUGF(infof(data,
"schannel: SSL/TLS connection with %s port %hu (step 1/3)",
hostname, conn->remote_port));
- if(curlx_verify_windows_version(5, 1, PLATFORM_WINNT,
+ if(curlx_verify_windows_version(5, 1, 0, PLATFORM_WINNT,
VERSION_LESS_THAN_EQUAL)) {
/* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
algorithms that may not be supported by all servers. */
@@ -785,29 +785,29 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#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. */
- BACKEND->use_alpn = conn->bits.tls_enable_alpn &&
+ backend->use_alpn = conn->bits.tls_enable_alpn &&
!GetProcAddress(GetModuleHandle(TEXT("ntdll")),
"wine_get_version") &&
- curlx_verify_windows_version(6, 3, PLATFORM_WINNT,
+ curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL);
#else
- BACKEND->use_alpn = false;
+ backend->use_alpn = false;
#endif
#ifdef _WIN32_WCE
#ifdef HAS_MANUAL_VERIFY_API
/* certificate validation on CE doesn't seem to work right; we'll
* do it following a more manual process. */
- BACKEND->use_manual_cred_validation = true;
+ backend->use_manual_cred_validation = true;
#else
#error "compiler too old to support requisite manual cert verify for Win CE"
#endif
#else
#ifdef HAS_MANUAL_VERIFY_API
if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) {
- if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT,
+ if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
- BACKEND->use_manual_cred_validation = true;
+ backend->use_manual_cred_validation = true;
}
else {
failf(data, "schannel: this version of Windows is too old to support "
@@ -816,7 +816,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
}
else
- BACKEND->use_manual_cred_validation = false;
+ backend->use_manual_cred_validation = false;
#else
if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) {
failf(data, "schannel: CA cert support not built in");
@@ -825,7 +825,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif
#endif
- BACKEND->cred = NULL;
+ backend->cred = NULL;
/* check for an existing re-usable credential handle */
if(SSL_SET_OPTION(primary.sessionid)) {
@@ -833,19 +833,19 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
if(!Curl_ssl_getsessionid(data, conn,
SSL_IS_PROXY() ? TRUE : FALSE,
(void **)&old_cred, NULL, sockindex)) {
- BACKEND->cred = old_cred;
+ backend->cred = old_cred;
DEBUGF(infof(data, "schannel: re-using existing credential handle"));
/* increment the reference counter of the credential/session handle */
- BACKEND->cred->refcount++;
+ backend->cred->refcount++;
DEBUGF(infof(data,
"schannel: incremented credential handle refcount = %d",
- BACKEND->cred->refcount));
+ backend->cred->refcount));
}
Curl_ssl_sessionid_unlock(data);
}
- if(!BACKEND->cred) {
+ if(!backend->cred) {
result = schannel_acquire_credential_handle(data, conn, sockindex);
if(result != CURLE_OK) {
return result;
@@ -862,7 +862,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
}
#ifdef HAS_ALPN
- if(BACKEND->use_alpn) {
+ if(backend->use_alpn) {
int cur = 0;
int list_start_index = 0;
unsigned int *extension_len = NULL;
@@ -920,18 +920,18 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
/* security request flags */
- BACKEND->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;
if(!SSL_SET_OPTION(auto_client_cert)) {
- BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+ backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
}
/* allocate memory for the security context handle */
- BACKEND->ctxt = (struct Curl_schannel_ctxt *)
+ backend->ctxt = (struct Curl_schannel_ctxt *)
calloc(1, sizeof(struct Curl_schannel_ctxt));
- if(!BACKEND->ctxt) {
+ if(!backend->ctxt) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
@@ -948,16 +948,16 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
us problems with inbuf regardless. https://github.com/curl/curl/issues/983
*/
sspi_status = s_pSecFn->InitializeSecurityContext(
- &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);
+ &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);
curlx_unicodefree(host_name);
if(sspi_status != SEC_I_CONTINUE_NEEDED) {
char buffer[STRERROR_LEN];
- Curl_safefree(BACKEND->ctxt);
+ Curl_safefree(backend->ctxt);
switch(sspi_status) {
case SEC_E_INSUFFICIENT_MEMORY:
failf(data, "schannel: initial InitializeSecurityContext failed: %s",
@@ -1001,10 +1001,10 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
DEBUGF(infof(data, "schannel: sent initial handshake data: "
"sent %zd bytes", written));
- BACKEND->recv_unrecoverable_err = CURLE_OK;
- BACKEND->recv_sspi_close_notify = false;
- BACKEND->recv_connection_closed = false;
- BACKEND->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;
@@ -1029,6 +1029,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
bool doread;
char * const hostname = SSL_HOST_NAME();
const char *pubkey_ptr;
+ struct ssl_backend_data *backend = connssl->backend;
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
@@ -1036,39 +1037,39 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
"schannel: SSL/TLS connection with %s port %hu (step 2/3)",
hostname, conn->remote_port));
- if(!BACKEND->cred || !BACKEND->ctxt)
+ if(!backend->cred || !backend->ctxt)
return CURLE_SSL_CONNECT_ERROR;
/* buffer to store previously received and decrypted data */
- if(!BACKEND->decdata_buffer) {
- BACKEND->decdata_offset = 0;
- BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
- BACKEND->decdata_buffer = malloc(BACKEND->decdata_length);
- if(!BACKEND->decdata_buffer) {
+ if(!backend->decdata_buffer) {
+ backend->decdata_offset = 0;
+ backend->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+ backend->decdata_buffer = malloc(backend->decdata_length);
+ if(!backend->decdata_buffer) {
failf(data, "schannel: unable to allocate memory");
return CURLE_OUT_OF_MEMORY;
}
}
/* buffer to store previously received and encrypted data */
- if(!BACKEND->encdata_buffer) {
- 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) {
+ if(!backend->encdata_buffer) {
+ 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) {
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(BACKEND->encdata_length - BACKEND->encdata_offset <
+ if(backend->encdata_length - backend->encdata_offset <
CURL_SCHANNEL_BUFFER_FREE_SIZE) {
/* increase internal encrypted data buffer */
- size_t reallocated_length = BACKEND->encdata_offset +
+ size_t reallocated_length = backend->encdata_offset +
CURL_SCHANNEL_BUFFER_FREE_SIZE;
- reallocated_buffer = realloc(BACKEND->encdata_buffer,
+ reallocated_buffer = realloc(backend->encdata_buffer,
reallocated_length);
if(!reallocated_buffer) {
@@ -1076,8 +1077,8 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
}
else {
- BACKEND->encdata_buffer = reallocated_buffer;
- BACKEND->encdata_length = reallocated_length;
+ backend->encdata_buffer = reallocated_buffer;
+ backend->encdata_length = reallocated_length;
}
}
@@ -1086,10 +1087,10 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
if(doread) {
/* read encrypted handshake data from socket */
result = Curl_read_plain(conn->sock[sockindex],
- (char *) (BACKEND->encdata_buffer +
- BACKEND->encdata_offset),
- BACKEND->encdata_length -
- BACKEND->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)
@@ -1105,18 +1106,18 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
/* increase encrypted data buffer offset */
- BACKEND->encdata_offset += nread;
- BACKEND->encdata_is_incomplete = false;
+ backend->encdata_offset += nread;
+ backend->encdata_is_incomplete = false;
DEBUGF(infof(data, "schannel: encrypted data got %zd", nread));
}
DEBUGF(infof(data,
"schannel: encrypted data buffer: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
/* setup input buffers */
- InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset),
- curlx_uztoul(BACKEND->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);
@@ -1132,17 +1133,17 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
/* copy received handshake data into input buffer */
- memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer,
- BACKEND->encdata_offset);
+ memcpy(inbuf[0].pvBuffer, backend->encdata_buffer,
+ backend->encdata_offset);
host_name = curlx_convert_UTF8_to_tchar(hostname);
if(!host_name)
return CURLE_OUT_OF_MEMORY;
sspi_status = s_pSecFn->InitializeSecurityContext(
- &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);
+ &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);
curlx_unicodefree(host_name);
@@ -1151,7 +1152,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* check if the handshake was incomplete */
if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
- BACKEND->encdata_is_incomplete = true;
+ backend->encdata_is_incomplete = true;
connssl->connecting_state = ssl_connect_2_reading;
DEBUGF(infof(data,
"schannel: received incomplete message, need more data"));
@@ -1162,8 +1163,8 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
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 &&
- !(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
- BACKEND->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;
DEBUGF(infof(data,
"schannel: a client certificate has been requested"));
@@ -1191,7 +1192,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
/* free obsolete buffer */
- if(outbuf[i].pvBuffer != NULL) {
+ if(outbuf[i].pvBuffer) {
s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer);
}
}
@@ -1245,11 +1246,11 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
*/
/* check if the remaining data is less than the total amount
and therefore begins after the already processed data */
- if(BACKEND->encdata_offset > inbuf[1].cbBuffer) {
- memmove(BACKEND->encdata_buffer,
- (BACKEND->encdata_buffer + BACKEND->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);
- BACKEND->encdata_offset = inbuf[1].cbBuffer;
+ backend->encdata_offset = inbuf[1].cbBuffer;
if(sspi_status == SEC_I_CONTINUE_NEEDED) {
doread = FALSE;
continue;
@@ -1257,7 +1258,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
}
else {
- BACKEND->encdata_offset = 0;
+ backend->encdata_offset = 0;
}
break;
}
@@ -1284,7 +1285,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
#ifdef HAS_MANUAL_VERIFY_API
- if(conn->ssl_config.verifypeer && BACKEND->use_manual_cred_validation) {
+ if(conn->ssl_config.verifypeer && backend->use_manual_cred_validation) {
return Curl_verify_certificate(data, conn, sockindex);
}
#endif
@@ -1366,6 +1367,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
#ifdef HAS_ALPN
SecPkgContext_ApplicationProtocol alpn_result;
#endif
+ struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
@@ -1373,28 +1375,28 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
"schannel: SSL/TLS connection with %s port %hu (step 3/3)",
hostname, conn->remote_port));
- if(!BACKEND->cred)
+ if(!backend->cred)
return CURLE_SSL_CONNECT_ERROR;
/* check if the required context attributes are met */
- if(BACKEND->ret_flags != BACKEND->req_flags) {
- if(!(BACKEND->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(!(BACKEND->ret_flags & ISC_RET_REPLAY_DETECT))
+ if(!(backend->ret_flags & ISC_RET_REPLAY_DETECT))
failf(data, "schannel: failed to setup replay detection");
- if(!(BACKEND->ret_flags & ISC_RET_CONFIDENTIALITY))
+ if(!(backend->ret_flags & ISC_RET_CONFIDENTIALITY))
failf(data, "schannel: failed to setup confidentiality");
- if(!(BACKEND->ret_flags & ISC_RET_ALLOCATED_MEMORY))
+ if(!(backend->ret_flags & ISC_RET_ALLOCATED_MEMORY))
failf(data, "schannel: failed to setup memory allocation");
- if(!(BACKEND->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(BACKEND->use_alpn) {
+ if(backend->use_alpn) {
sspi_status =
- s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
SECPKG_ATTR_APPLICATION_PROTOCOL,
&alpn_result);
@@ -1439,7 +1441,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
incache = !(Curl_ssl_getsessionid(data, conn, isproxy, (void **)&old_cred,
NULL, sockindex));
if(incache) {
- if(old_cred != BACKEND->cred) {
+ if(old_cred != backend->cred) {
DEBUGF(infof(data,
"schannel: old credential handle is stale, removing"));
/* we're not taking old_cred ownership here, no refcount++ is needed */
@@ -1448,7 +1450,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
}
if(!incache) {
- result = Curl_ssl_addsessionid(data, conn, isproxy, BACKEND->cred,
+ result = Curl_ssl_addsessionid(data, conn, isproxy, backend->cred,
sizeof(struct Curl_schannel_cred),
sockindex, &added);
if(result) {
@@ -1458,7 +1460,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
else if(added) {
/* this cred session is now also referenced by sessionid cache */
- BACKEND->cred->refcount++;
+ backend->cred->refcount++;
DEBUGF(infof(data,
"schannel: stored credential handle in session cache"));
}
@@ -1469,7 +1471,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
if(data->set.ssl.certinfo) {
int certs_count = 0;
sspi_status =
- s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&ccert_context);
@@ -1606,7 +1608,10 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
* binding to pass the IIS extended protection checks.
* Available on Windows 7 or later.
*/
- conn->sslContext = &BACKEND->ctxt->ctxt_handle;
+ {
+ struct ssl_backend_data *backend = connssl->backend;
+ conn->sslContext = &backend->ctxt->ctxt_handle;
+ }
#endif
*done = TRUE;
@@ -1633,13 +1638,14 @@ schannel_send(struct Curl_easy *data, int sockindex,
SecBufferDesc outbuf_desc;
SECURITY_STATUS sspi_status = SEC_E_OK;
CURLcode result;
+ struct ssl_backend_data *backend = connssl->backend;
/* check if the maximum stream sizes were queried */
- if(BACKEND->stream_sizes.cbMaximumMessage == 0) {
+ if(backend->stream_sizes.cbMaximumMessage == 0) {
sspi_status = s_pSecFn->QueryContextAttributes(
- &BACKEND->ctxt->ctxt_handle,
+ &backend->ctxt->ctxt_handle,
SECPKG_ATTR_STREAM_SIZES,
- &BACKEND->stream_sizes);
+ &backend->stream_sizes);
if(sspi_status != SEC_E_OK) {
*err = CURLE_SEND_ERROR;
return -1;
@@ -1647,13 +1653,13 @@ schannel_send(struct Curl_easy *data, int sockindex,
}
/* check if the buffer is longer than the maximum message length */
- if(len > BACKEND->stream_sizes.cbMaximumMessage) {
- len = BACKEND->stream_sizes.cbMaximumMessage;
+ if(len > backend->stream_sizes.cbMaximumMessage) {
+ len = backend->stream_sizes.cbMaximumMessage;
}
/* calculate the complete message length and allocate a buffer for it */
- data_len = BACKEND->stream_sizes.cbHeader + len +
- BACKEND->stream_sizes.cbTrailer;
+ data_len = backend->stream_sizes.cbHeader + len +
+ backend->stream_sizes.cbTrailer;
ptr = (unsigned char *) malloc(data_len);
if(!ptr) {
*err = CURLE_OUT_OF_MEMORY;
@@ -1662,12 +1668,12 @@ schannel_send(struct Curl_easy *data, int sockindex,
/* setup output buffers (header, data, trailer, empty) */
InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
- ptr, BACKEND->stream_sizes.cbHeader);
+ ptr, backend->stream_sizes.cbHeader);
InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
- ptr + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
+ ptr + backend->stream_sizes.cbHeader, curlx_uztoul(len));
InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
- ptr + BACKEND->stream_sizes.cbHeader + len,
- BACKEND->stream_sizes.cbTrailer);
+ ptr + backend->stream_sizes.cbHeader + len,
+ backend->stream_sizes.cbTrailer);
InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
InitSecBufferDesc(&outbuf_desc, outbuf, 4);
@@ -1675,7 +1681,7 @@ schannel_send(struct Curl_easy *data, int sockindex,
memcpy(outbuf[1].pvBuffer, buf, len);
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
- sspi_status = s_pSecFn->EncryptMessage(&BACKEND->ctxt->ctxt_handle, 0,
+ sspi_status = s_pSecFn->EncryptMessage(&backend->ctxt->ctxt_handle, 0,
&outbuf_desc, 0);
/* check if the message was encrypted */
@@ -1780,9 +1786,10 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* we want the length of the encrypted buffer to be at least large enough
that it can hold all the bytes requested and some TLS record overhead. */
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
+ struct ssl_backend_data *backend = connssl->backend;
/****************************************************************************
- * Don't return or set BACKEND->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
@@ -1794,16 +1801,16 @@ schannel_recv(struct Curl_easy *data, int sockindex,
DEBUGF(infof(data, "schannel: client wants to read %zu bytes", len));
*err = CURLE_OK;
- if(len && len <= BACKEND->decdata_offset) {
+ if(len && len <= backend->decdata_offset) {
infof(data, "schannel: enough decrypted data is already available");
goto cleanup;
}
- else if(BACKEND->recv_unrecoverable_err) {
- *err = BACKEND->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");
goto cleanup;
}
- else if(BACKEND->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");
goto cleanup;
@@ -1813,17 +1820,17 @@ schannel_recv(struct Curl_easy *data, int sockindex,
immediately because there may be data to decrypt (in the case we want to
decrypt all encrypted cached data) so handle !len later in cleanup.
*/
- else if(len && !BACKEND->recv_connection_closed) {
+ else if(len && !backend->recv_connection_closed) {
/* increase enc buffer in order to fit the requested amount of data */
- size = BACKEND->encdata_length - BACKEND->encdata_offset;
+ size = backend->encdata_length - backend->encdata_offset;
if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
- BACKEND->encdata_length < min_encdata_length) {
- reallocated_length = BACKEND->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(BACKEND->encdata_buffer,
+ reallocated_buffer = realloc(backend->encdata_buffer,
reallocated_length);
if(!reallocated_buffer) {
*err = CURLE_OUT_OF_MEMORY;
@@ -1831,21 +1838,21 @@ schannel_recv(struct Curl_easy *data, int sockindex,
goto cleanup;
}
- BACKEND->encdata_buffer = reallocated_buffer;
- BACKEND->encdata_length = reallocated_length;
- size = BACKEND->encdata_length - BACKEND->encdata_offset;
+ backend->encdata_buffer = reallocated_buffer;
+ backend->encdata_length = reallocated_length;
+ size = backend->encdata_length - backend->encdata_offset;
DEBUGF(infof(data, "schannel: encdata_buffer resized %zu",
- BACKEND->encdata_length));
+ backend->encdata_length));
}
DEBUGF(infof(data,
"schannel: encrypted data buffer: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
/* read encrypted data from socket */
*err = Curl_read_plain(conn->sock[sockindex],
- (char *)(BACKEND->encdata_buffer +
- BACKEND->encdata_offset),
+ (char *)(backend->encdata_buffer +
+ backend->encdata_offset),
size, &nread);
if(*err) {
nread = -1;
@@ -1858,27 +1865,27 @@ schannel_recv(struct Curl_easy *data, int sockindex,
infof(data, "schannel: Curl_read_plain returned error %d", *err);
}
else if(nread == 0) {
- BACKEND->recv_connection_closed = true;
+ backend->recv_connection_closed = true;
DEBUGF(infof(data, "schannel: server closed the connection"));
}
else if(nread > 0) {
- BACKEND->encdata_offset += (size_t)nread;
- BACKEND->encdata_is_incomplete = false;
+ backend->encdata_offset += (size_t)nread;
+ backend->encdata_is_incomplete = false;
DEBUGF(infof(data, "schannel: encrypted data got %zd", nread));
}
}
DEBUGF(infof(data,
"schannel: encrypted data buffer: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
/* decrypt loop */
- while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK &&
- (!len || BACKEND->decdata_offset < len ||
- BACKEND->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, BACKEND->encdata_buffer,
- curlx_uztoul(BACKEND->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);
@@ -1888,7 +1895,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
*/
- sspi_status = s_pSecFn->DecryptMessage(&BACKEND->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
@@ -1904,37 +1911,37 @@ schannel_recv(struct Curl_easy *data, 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(BACKEND->decdata_length - BACKEND->decdata_offset < size ||
- BACKEND->decdata_length < len) {
+ if(backend->decdata_length - backend->decdata_offset < size ||
+ backend->decdata_length < len) {
/* increase internal decrypted data buffer */
- reallocated_length = BACKEND->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(BACKEND->decdata_buffer,
+ reallocated_buffer = realloc(backend->decdata_buffer,
reallocated_length);
if(!reallocated_buffer) {
*err = CURLE_OUT_OF_MEMORY;
failf(data, "schannel: unable to re-allocate memory");
goto cleanup;
}
- BACKEND->decdata_buffer = reallocated_buffer;
- BACKEND->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(BACKEND->decdata_buffer + BACKEND->decdata_offset,
+ memcpy(backend->decdata_buffer + backend->decdata_offset,
inbuf[1].pvBuffer, size);
- BACKEND->decdata_offset += size;
+ backend->decdata_offset += size;
}
DEBUGF(infof(data, "schannel: decrypted data added: %zu", size));
DEBUGF(infof(data,
"schannel: decrypted cached: offset %zu length %zu",
- BACKEND->decdata_offset, BACKEND->decdata_length));
+ backend->decdata_offset, backend->decdata_length));
}
/* check for remaining encrypted data */
@@ -1945,22 +1952,22 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* check if the remaining data is less than the total amount
* and therefore begins after the already processed data
*/
- if(BACKEND->encdata_offset > inbuf[3].cbBuffer) {
+ if(backend->encdata_offset > inbuf[3].cbBuffer) {
/* move remaining encrypted data forward to the beginning of
buffer */
- memmove(BACKEND->encdata_buffer,
- (BACKEND->encdata_buffer + BACKEND->encdata_offset) -
+ memmove(backend->encdata_buffer,
+ (backend->encdata_buffer + backend->encdata_offset) -
inbuf[3].cbBuffer, inbuf[3].cbBuffer);
- BACKEND->encdata_offset = inbuf[3].cbBuffer;
+ backend->encdata_offset = inbuf[3].cbBuffer;
}
DEBUGF(infof(data,
"schannel: encrypted cached: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
}
else {
/* reset encrypted buffer offset, because there is no data remaining */
- BACKEND->encdata_offset = 0;
+ backend->encdata_offset = 0;
}
/* check if server wants to renegotiate the connection context */
@@ -1970,7 +1977,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
infof(data, "schannel: can't renegotiate, an error is pending");
goto cleanup;
}
- if(BACKEND->encdata_offset) {
+ if(backend->encdata_offset) {
*err = CURLE_RECV_ERROR;
infof(data, "schannel: can't renegotiate, "
"encrypted data available");
@@ -1994,16 +2001,16 @@ schannel_recv(struct Curl_easy *data, 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. */
- BACKEND->recv_sspi_close_notify = true;
- if(!BACKEND->recv_connection_closed) {
- BACKEND->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");
}
goto cleanup;
}
}
else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
- BACKEND->encdata_is_incomplete = true;
+ backend->encdata_is_incomplete = true;
if(!*err)
*err = CURLE_AGAIN;
infof(data, "schannel: failed to decrypt data, need more data");
@@ -2022,11 +2029,11 @@ schannel_recv(struct Curl_easy *data, int sockindex,
DEBUGF(infof(data,
"schannel: encrypted data buffer: offset %zu length %zu",
- BACKEND->encdata_offset, BACKEND->encdata_length));
+ backend->encdata_offset, backend->encdata_length));
DEBUGF(infof(data,
"schannel: decrypted data buffer: offset %zu length %zu",
- BACKEND->decdata_offset, BACKEND->decdata_length));
+ backend->decdata_offset, backend->decdata_length));
cleanup:
/* Warning- there is no guarantee the encdata state is valid at this point */
@@ -2043,13 +2050,13 @@ schannel_recv(struct Curl_easy *data, int sockindex,
assume it was graceful (close_notify) since there doesn't seem to be a
way to tell.
*/
- if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed &&
- !BACKEND->recv_sspi_close_notify) {
- bool isWin2k = curlx_verify_windows_version(5, 0, PLATFORM_WINNT,
+ if(len && !backend->decdata_offset && backend->recv_connection_closed &&
+ !backend->recv_sspi_close_notify) {
+ bool isWin2k = curlx_verify_windows_version(5, 0, 0, PLATFORM_WINNT,
VERSION_EQUAL);
if(isWin2k && sspi_status == SEC_E_OK)
- BACKEND->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)");
@@ -2058,23 +2065,23 @@ schannel_recv(struct Curl_easy *data, int sockindex,
/* Any error other than CURLE_AGAIN is an unrecoverable error. */
if(*err && *err != CURLE_AGAIN)
- BACKEND->recv_unrecoverable_err = *err;
+ backend->recv_unrecoverable_err = *err;
- size = len < BACKEND->decdata_offset ? len : BACKEND->decdata_offset;
+ size = len < backend->decdata_offset ? len : backend->decdata_offset;
if(size) {
- memcpy(buf, BACKEND->decdata_buffer, size);
- memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size,
- BACKEND->decdata_offset - size);
- BACKEND->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;
DEBUGF(infof(data, "schannel: decrypted data returned %zu", size));
DEBUGF(infof(data,
"schannel: decrypted data buffer: offset %zu length %zu",
- BACKEND->decdata_offset, BACKEND->decdata_length));
+ backend->decdata_offset, backend->decdata_length));
*err = CURLE_OK;
return (ssize_t)size;
}
- if(!*err && !BACKEND->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
@@ -2113,10 +2120,11 @@ static bool schannel_data_pending(const struct connectdata *conn,
int sockindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
if(connssl->use) /* SSL/TLS is in use */
- return (BACKEND->decdata_offset > 0 ||
- (BACKEND->encdata_offset > 0 && !BACKEND->encdata_is_incomplete));
+ return (backend->decdata_offset > 0 ||
+ (backend->encdata_offset > 0 && !backend->encdata_is_incomplete));
else
return FALSE;
}
@@ -2146,6 +2154,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
*/
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
char * const hostname = SSL_HOST_NAME();
+ struct ssl_backend_data *backend = connssl->backend;
DEBUGASSERT(data);
@@ -2154,7 +2163,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
hostname, conn->remote_port);
}
- if(connssl->use && BACKEND->cred && BACKEND->ctxt) {
+ if(connssl->use && backend->cred && backend->ctxt) {
SecBufferDesc BuffDesc;
SecBuffer Buffer;
SECURITY_STATUS sspi_status;
@@ -2167,7 +2176,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
InitSecBufferDesc(&BuffDesc, &Buffer, 1);
- sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle,
+ sspi_status = s_pSecFn->ApplyControlToken(&backend->ctxt->ctxt_handle,
&BuffDesc);
if(sspi_status != SEC_E_OK) {
@@ -2185,18 +2194,18 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
sspi_status = s_pSecFn->InitializeSecurityContext(
- &BACKEND->cred->cred_handle,
- &BACKEND->ctxt->ctxt_handle,
+ &backend->cred->cred_handle,
+ &backend->ctxt->ctxt_handle,
host_name,
- BACKEND->req_flags,
+ backend->req_flags,
0,
0,
NULL,
0,
- &BACKEND->ctxt->ctxt_handle,
+ &backend->ctxt->ctxt_handle,
&outbuf_desc,
- &BACKEND->ret_flags,
- &BACKEND->ctxt->time_stamp);
+ &backend->ret_flags,
+ &backend->ctxt->time_stamp);
curlx_unicodefree(host_name);
@@ -2215,33 +2224,33 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
}
/* free SSPI Schannel API security context handle */
- if(BACKEND->ctxt) {
+ if(backend->ctxt) {
DEBUGF(infof(data, "schannel: clear security context handle"));
- s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle);
- Curl_safefree(BACKEND->ctxt);
+ s_pSecFn->DeleteSecurityContext(&backend->ctxt->ctxt_handle);
+ Curl_safefree(backend->ctxt);
}
/* free SSPI Schannel API credential handle */
- if(BACKEND->cred) {
+ if(backend->cred) {
Curl_ssl_sessionid_lock(data);
- schannel_session_free(BACKEND->cred);
+ schannel_session_free(backend->cred);
Curl_ssl_sessionid_unlock(data);
- BACKEND->cred = NULL;
+ backend->cred = NULL;
}
/* free internal buffer for received encrypted data */
- if(BACKEND->encdata_buffer != NULL) {
- Curl_safefree(BACKEND->encdata_buffer);
- BACKEND->encdata_length = 0;
- BACKEND->encdata_offset = 0;
- BACKEND->encdata_is_incomplete = false;
+ if(backend->encdata_buffer) {
+ 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(BACKEND->decdata_buffer != NULL) {
- Curl_safefree(BACKEND->decdata_buffer);
- BACKEND->decdata_length = 0;
- BACKEND->decdata_offset = 0;
+ if(backend->decdata_buffer) {
+ Curl_safefree(backend->decdata_buffer);
+ backend->decdata_length = 0;
+ backend->decdata_offset = 0;
}
return CURLE_OK;
@@ -2299,6 +2308,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
const char *pinnedpubkey)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
CERT_CONTEXT *pCertContextServer = NULL;
/* Result is returned to caller */
@@ -2316,7 +2326,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
struct Curl_asn1Element *pubkey;
sspi_status =
- s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+ s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&pCertContextServer);
@@ -2422,8 +2432,9 @@ static CURLcode schannel_sha256sum(const unsigned char *input,
static void *schannel_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
+ struct ssl_backend_data *backend = connssl->backend;
(void)info;
- return &BACKEND->ctxt->ctxt_handle;
+ return &backend->ctxt->ctxt_handle;
}
const struct Curl_ssl Curl_ssl_schannel = {
diff --git a/contrib/libs/curl/lib/vtls/schannel_verify.c b/contrib/libs/curl/lib/vtls/schannel_verify.c
index 1b283d0453..4966cd4945 100644
--- a/contrib/libs/curl/lib/vtls/schannel_verify.c
+++ b/contrib/libs/curl/lib/vtls/schannel_verify.c
@@ -355,7 +355,7 @@ static DWORD cert_get_name_string(struct Curl_easy *data,
DWORD i;
/* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */
- if(curlx_verify_windows_version(6, 2, PLATFORM_WINNT,
+ if(curlx_verify_windows_version(6, 2, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
/* CertGetNameString will provide the 8-bit character string without
@@ -597,7 +597,8 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
* trusted certificates. This is only supported on Windows 7+.
*/
- if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_LESS_THAN)) {
+ if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
+ VERSION_LESS_THAN)) {
failf(data, "schannel: this version of Windows is too old to support "
"certificate verification via CA bundle file.");
result = CURLE_SSL_CACERT_BADFILE;
diff --git a/contrib/libs/curl/lib/vtls/sectransp.c b/contrib/libs/curl/lib/vtls/sectransp.c
index 0bf515460d..f7a20b20b1 100644
--- a/contrib/libs/curl/lib/vtls/sectransp.c
+++ b/contrib/libs/curl/lib/vtls/sectransp.c
@@ -997,14 +997,14 @@ CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
#else
#if CURL_BUILD_MAC_10_7
/* Lion & later: Get the long description if we can. */
- if(SecCertificateCopyLongDescription != NULL)
+ if(SecCertificateCopyLongDescription)
server_cert_summary =
SecCertificateCopyLongDescription(NULL, cert, NULL);
else
#endif /* CURL_BUILD_MAC_10_7 */
#if CURL_BUILD_MAC_10_6
/* Snow Leopard: Get the certificate summary. */
- if(SecCertificateCopySubjectSummary != NULL)
+ if(SecCertificateCopySubjectSummary)
server_cert_summary = SecCertificateCopySubjectSummary(cert);
else
#endif /* CURL_BUILD_MAC_10_6 */
@@ -1118,7 +1118,7 @@ static OSStatus CopyIdentityWithLabel(char *label,
/* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
kSecClassIdentity was introduced in Lion. If both exist, let's use them
to find the certificate. */
- if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
+ if(SecItemCopyMatching && kSecClassIdentity) {
CFTypeRef keys[5];
CFTypeRef values[5];
CFDictionaryRef query_dict;
@@ -1248,7 +1248,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
password ? 1L : 0L, NULL, NULL);
- if(options != NULL) {
+ if(options) {
status = SecPKCS12Import(pkcs_data, options, &items);
CFRelease(options);
}
@@ -1406,7 +1406,7 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
}
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
- if(SSLSetProtocolVersionMax != NULL) {
+ if(SSLSetProtocolVersionMax) {
SSLProtocol darwin_ver_min = kTLSProtocol1;
SSLProtocol darwin_ver_max = kTLSProtocol1;
CURLcode result = sectransp_version_from_curl(&darwin_ver_min,
@@ -1608,7 +1608,7 @@ static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data,
if(tls_name) {
table_cipher_name = ciphertable[i].name;
}
- else if(ciphertable[i].alias_name != NULL) {
+ else if(ciphertable[i].alias_name) {
table_cipher_name = ciphertable[i].alias_name;
}
else {
@@ -1688,7 +1688,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#endif /* CURL_BUILD_MAC */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
- if(SSLCreateContext != NULL) { /* use the newer API if available */
+ if(SSLCreateContext) { /* use the newer API if available */
if(backend->ssl_ctx)
CFRelease(backend->ssl_ctx);
backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
@@ -1722,7 +1722,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
/* check to see if we've been told to use an explicit SSL/TLS version */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
- if(SSLSetProtocolVersionMax != NULL) {
+ if(SSLSetProtocolVersionMax) {
switch(conn->ssl_config.version) {
case CURL_SSLVERSION_TLSv1:
(void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
@@ -1980,9 +1980,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
Darwin 15.x.x is El Capitan (10.11)
*/
#if CURL_BUILD_MAC
- if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
+ if(SSLSetSessionOption && darwinver_maj >= 13) {
#else
- if(SSLSetSessionOption != NULL) {
+ if(SSLSetSessionOption) {
#endif /* CURL_BUILD_MAC */
bool break_on_auth = !conn->ssl_config.verifypeer ||
ssl_cafile || ssl_cablob;
@@ -2065,7 +2065,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
/* We want to enable 1/n-1 when using a CBC cipher unless the user
specifically doesn't want us doing that: */
- if(SSLSetSessionOption != NULL) {
+ if(SSLSetSessionOption) {
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
!SSL_SET_OPTION(enable_beast));
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
@@ -2521,7 +2521,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
} while(0);
Curl_safefree(realpubkey);
- if(publicKeyBits != NULL)
+ if(publicKeyBits)
CFRelease(publicKeyBits);
return result;
@@ -2947,7 +2947,7 @@ collect_server_cert(struct Curl_easy *data,
private API and doesn't work as expected. So we have to look for
a different symbol to make sure this code is only executed under
Lion or later. */
- if(SecTrustEvaluateAsync != NULL) {
+ if(SecTrustEvaluateAsync) {
#pragma unused(server_certs)
err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
@@ -3165,7 +3165,7 @@ static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
if(backend->ssl_ctx) {
(void)SSLClose(backend->ssl_ctx);
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
- if(SSLCreateContext != NULL)
+ if(SSLCreateContext)
CFRelease(backend->ssl_ctx);
#if CURL_SUPPORT_MAC_10_8
else
@@ -3329,7 +3329,7 @@ static CURLcode sectransp_sha256sum(const unsigned char *tmp, /* input */
static bool sectransp_false_start(void)
{
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
- if(SSLSetSessionOption != NULL)
+ if(SSLSetSessionOption)
return TRUE;
#endif
return FALSE;