diff options
author | thegeorg <thegeorg@yandex-team.ru> | 2022-04-20 17:40:08 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.ru> | 2022-04-20 17:40:08 +0300 |
commit | 31ff69685d432e9506ba2cad2e4cb05528021282 (patch) | |
tree | 70ed539fcc48dd4d1981fd4785797a11cd7e4006 /contrib/libs/curl/lib/vtls | |
parent | 9abb1ba6ed6c2852738c0f69367b9c0bff668676 (diff) | |
download | ydb-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.c | 34 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/gtls.h | 8 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/mbedtls.c | 53 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/mesalink.c | 91 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/nss.c | 100 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/openssl.c | 180 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/openssl.h | 8 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/rustls.c | 61 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/schannel.c | 397 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/schannel_verify.c | 5 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/sectransp.c | 30 |
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; |