diff options
author | thegeorg <thegeorg@yandex-team.ru> | 2022-02-10 16:45:08 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:08 +0300 |
commit | 4e839db24a3bbc9f1c610c43d6faaaa99824dcca (patch) | |
tree | 506dac10f5df94fab310584ee51b24fc5a081c22 /contrib/libs/curl/lib/vtls | |
parent | 2d37894b1b037cf24231090eda8589bbb44fb6fc (diff) | |
download | ydb-4e839db24a3bbc9f1c610c43d6faaaa99824dcca.tar.gz |
Restoring authorship annotation for <thegeorg@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/curl/lib/vtls')
26 files changed, 3722 insertions, 3722 deletions
diff --git a/contrib/libs/curl/lib/vtls/bearssl.c b/contrib/libs/curl/lib/vtls/bearssl.c index b0c3dc2f07..8599844c1d 100644 --- a/contrib/libs/curl/lib/vtls/bearssl.c +++ b/contrib/libs/curl/lib/vtls/bearssl.c @@ -1,877 +1,877 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2019 - 2020, Michael Forney, <mforney@mforney.org> - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_BEARSSL - -#include <bearssl.h> - -#include "bearssl.h" -#include "urldata.h" -#include "sendf.h" -#include "inet_pton.h" -#include "vtls.h" -#include "connect.h" -#include "select.h" -#include "multiif.h" -#include "curl_printf.h" -#include "curl_memory.h" - -struct x509_context { - const br_x509_class *vtable; - br_x509_minimal_context minimal; - bool verifyhost; - bool verifypeer; -}; - -struct ssl_backend_data { - br_ssl_client_context ctx; - struct x509_context x509; - unsigned char buf[BR_SSL_BUFSIZE_BIDI]; - br_x509_trust_anchor *anchors; - size_t anchors_len; - const char *protocols[2]; - /* SSL client context is active */ - bool active; - /* size of pending write, yet to be flushed */ - size_t pending_write; -}; - -struct cafile_parser { - CURLcode err; - bool in_cert; - br_x509_decoder_context xc; - /* array of trust anchors loaded from CAfile */ - br_x509_trust_anchor *anchors; - size_t anchors_len; - /* buffer for DN data */ - unsigned char dn[1024]; - size_t dn_len; -}; - -static void append_dn(void *ctx, const void *buf, size_t len) -{ - struct cafile_parser *ca = ctx; - - if(ca->err != CURLE_OK || !ca->in_cert) - return; - if(sizeof(ca->dn) - ca->dn_len < len) { - ca->err = CURLE_FAILED_INIT; - return; - } - memcpy(ca->dn + ca->dn_len, buf, len); - ca->dn_len += len; -} - -static void x509_push(void *ctx, const void *buf, size_t len) -{ - struct cafile_parser *ca = ctx; - - if(ca->in_cert) - br_x509_decoder_push(&ca->xc, buf, len); -} - -static CURLcode load_cafile(const char *path, br_x509_trust_anchor **anchors, - size_t *anchors_len) -{ - struct cafile_parser ca; - br_pem_decoder_context pc; - br_x509_trust_anchor *ta; - size_t ta_size; - br_x509_trust_anchor *new_anchors; - size_t new_anchors_len; - br_x509_pkey *pkey; - FILE *fp; - unsigned char buf[BUFSIZ], *p; - const char *name; - size_t n, i, pushed; - - fp = fopen(path, "rb"); - if(!fp) - return CURLE_SSL_CACERT_BADFILE; - - ca.err = CURLE_OK; - ca.in_cert = FALSE; - ca.anchors = NULL; - ca.anchors_len = 0; - br_pem_decoder_init(&pc); - br_pem_decoder_setdest(&pc, x509_push, &ca); - for(;;) { - n = fread(buf, 1, sizeof(buf), fp); - if(n == 0) - break; - p = buf; - while(n) { - pushed = br_pem_decoder_push(&pc, p, n); - if(ca.err) - goto fail; - p += pushed; - n -= pushed; - - switch(br_pem_decoder_event(&pc)) { - case 0: - break; - case BR_PEM_BEGIN_OBJ: - name = br_pem_decoder_name(&pc); - if(strcmp(name, "CERTIFICATE") && strcmp(name, "X509 CERTIFICATE")) - break; - br_x509_decoder_init(&ca.xc, append_dn, &ca); - if(ca.anchors_len == SIZE_MAX / sizeof(ca.anchors[0])) { - ca.err = CURLE_OUT_OF_MEMORY; - goto fail; - } - new_anchors_len = ca.anchors_len + 1; - new_anchors = realloc(ca.anchors, - new_anchors_len * sizeof(ca.anchors[0])); - if(!new_anchors) { - ca.err = CURLE_OUT_OF_MEMORY; - goto fail; - } - ca.anchors = new_anchors; - ca.anchors_len = new_anchors_len; - ca.in_cert = TRUE; - ca.dn_len = 0; - ta = &ca.anchors[ca.anchors_len - 1]; - ta->dn.data = NULL; - break; - case BR_PEM_END_OBJ: - if(!ca.in_cert) - break; - ca.in_cert = FALSE; - if(br_x509_decoder_last_error(&ca.xc)) { - ca.err = CURLE_SSL_CACERT_BADFILE; - goto fail; - } - ta->flags = 0; - if(br_x509_decoder_isCA(&ca.xc)) - ta->flags |= BR_X509_TA_CA; - pkey = br_x509_decoder_get_pkey(&ca.xc); - if(!pkey) { - ca.err = CURLE_SSL_CACERT_BADFILE; - goto fail; - } - ta->pkey = *pkey; - - /* calculate space needed for trust anchor data */ - ta_size = ca.dn_len; - switch(pkey->key_type) { - case BR_KEYTYPE_RSA: - ta_size += pkey->key.rsa.nlen + pkey->key.rsa.elen; - break; - case BR_KEYTYPE_EC: - ta_size += pkey->key.ec.qlen; - break; - default: - ca.err = CURLE_FAILED_INIT; - goto fail; - } - - /* fill in trust anchor DN and public key data */ - ta->dn.data = malloc(ta_size); - if(!ta->dn.data) { - ca.err = CURLE_OUT_OF_MEMORY; - goto fail; - } - memcpy(ta->dn.data, ca.dn, ca.dn_len); - ta->dn.len = ca.dn_len; - switch(pkey->key_type) { - case BR_KEYTYPE_RSA: - ta->pkey.key.rsa.n = ta->dn.data + ta->dn.len; - memcpy(ta->pkey.key.rsa.n, pkey->key.rsa.n, pkey->key.rsa.nlen); - ta->pkey.key.rsa.e = ta->pkey.key.rsa.n + ta->pkey.key.rsa.nlen; - memcpy(ta->pkey.key.rsa.e, pkey->key.rsa.e, pkey->key.rsa.elen); - break; - case BR_KEYTYPE_EC: - ta->pkey.key.ec.q = ta->dn.data + ta->dn.len; - memcpy(ta->pkey.key.ec.q, pkey->key.ec.q, pkey->key.ec.qlen); - break; - } - break; - default: - ca.err = CURLE_SSL_CACERT_BADFILE; - goto fail; - } - } - } - if(ferror(fp)) - ca.err = CURLE_READ_ERROR; - -fail: - fclose(fp); - if(ca.err == CURLE_OK) { - *anchors = ca.anchors; - *anchors_len = ca.anchors_len; - } - else { - for(i = 0; i < ca.anchors_len; ++i) - free(ca.anchors[i].dn.data); - free(ca.anchors); - } - - return ca.err; -} - -static void x509_start_chain(const br_x509_class **ctx, - const char *server_name) -{ - struct x509_context *x509 = (struct x509_context *)ctx; - - if(!x509->verifyhost) - server_name = NULL; - x509->minimal.vtable->start_chain(&x509->minimal.vtable, server_name); -} - -static void x509_start_cert(const br_x509_class **ctx, uint32_t length) -{ - struct x509_context *x509 = (struct x509_context *)ctx; - - x509->minimal.vtable->start_cert(&x509->minimal.vtable, length); -} - -static void x509_append(const br_x509_class **ctx, const unsigned char *buf, - size_t len) -{ - struct x509_context *x509 = (struct x509_context *)ctx; - - x509->minimal.vtable->append(&x509->minimal.vtable, buf, len); -} - -static void x509_end_cert(const br_x509_class **ctx) -{ - struct x509_context *x509 = (struct x509_context *)ctx; - - x509->minimal.vtable->end_cert(&x509->minimal.vtable); -} - -static unsigned x509_end_chain(const br_x509_class **ctx) -{ - struct x509_context *x509 = (struct x509_context *)ctx; - unsigned err; - - err = x509->minimal.vtable->end_chain(&x509->minimal.vtable); - if(err && !x509->verifypeer) { - /* ignore any X.509 errors */ - err = BR_ERR_OK; - } - - return err; -} - -static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx, - unsigned *usages) -{ - struct x509_context *x509 = (struct x509_context *)ctx; - - return x509->minimal.vtable->get_pkey(&x509->minimal.vtable, usages); -} - -static const br_x509_class x509_vtable = { - sizeof(struct x509_context), - x509_start_chain, - x509_start_cert, - x509_append, - x509_end_cert, - x509_end_chain, - x509_get_pkey -}; - -static CURLcode bearssl_connect_step1(struct connectdata *conn, int sockindex) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); -#ifndef CURL_DISABLE_PROXY - const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - const char *hostname = conn->host.name; -#endif - const bool verifypeer = SSL_CONN_CONFIG(verifypeer); - const bool verifyhost = SSL_CONN_CONFIG(verifyhost); - CURLcode ret; - unsigned version_min, version_max; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif - - switch(SSL_CONN_CONFIG(version)) { - case CURL_SSLVERSION_SSLv2: - failf(data, "BearSSL does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_SSLv3: - failf(data, "BearSSL does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_TLSv1_0: - version_min = BR_TLS10; - version_max = BR_TLS10; - break; - case CURL_SSLVERSION_TLSv1_1: - version_min = BR_TLS11; - version_max = BR_TLS11; - break; - case CURL_SSLVERSION_TLSv1_2: - version_min = BR_TLS12; - version_max = BR_TLS12; - break; - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - version_min = BR_TLS10; - version_max = BR_TLS12; - break; - default: - failf(data, "BearSSL: unknown CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(ssl_cafile) { - ret = load_cafile(ssl_cafile, &backend->anchors, &backend->anchors_len); - if(ret != CURLE_OK) { - if(verifypeer) { - failf(data, "error setting certificate verify locations:\n" - " CAfile: %s\n", ssl_cafile); - return ret; - } - infof(data, "error setting certificate verify locations," - " continuing anyway:\n"); - } - } - - /* initialize SSL context */ - br_ssl_client_init_full(&backend->ctx, &backend->x509.minimal, - backend->anchors, backend->anchors_len); - br_ssl_engine_set_versions(&backend->ctx.eng, version_min, version_max); - br_ssl_engine_set_buffer(&backend->ctx.eng, backend->buf, - sizeof(backend->buf), 1); - - /* initialize X.509 context */ - backend->x509.vtable = &x509_vtable; - backend->x509.verifypeer = verifypeer; - backend->x509.verifyhost = verifyhost; - br_ssl_engine_set_x509(&backend->ctx.eng, &backend->x509.vtable); - - if(SSL_SET_OPTION(primary.sessionid)) { - void *session; - - Curl_ssl_sessionid_lock(conn); - if(!Curl_ssl_getsessionid(conn, &session, NULL, sockindex)) { - br_ssl_engine_set_session_parameters(&backend->ctx.eng, session); - infof(data, "BearSSL: re-using session ID\n"); - } - Curl_ssl_sessionid_unlock(conn); - } - - if(conn->bits.tls_enable_alpn) { - int cur = 0; - - /* NOTE: when adding more protocols here, increase the size of the - * protocols array in `struct ssl_backend_data`. - */ - -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 -#ifndef CURL_DISABLE_PROXY - && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) -#endif - ) { - backend->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); - } -#endif - - backend->protocols[cur++] = ALPN_HTTP_1_1; - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - - br_ssl_engine_set_protocol_names(&backend->ctx.eng, - backend->protocols, cur); - } - - if((1 == Curl_inet_pton(AF_INET, hostname, &addr)) -#ifdef ENABLE_IPV6 - || (1 == Curl_inet_pton(AF_INET6, hostname, &addr)) -#endif - ) { - if(verifyhost) { - failf(data, "BearSSL: " - "host verification of IP address is not supported"); - return CURLE_PEER_FAILED_VERIFICATION; - } - hostname = NULL; - } - - if(!br_ssl_client_reset(&backend->ctx, hostname, 0)) - return CURLE_FAILED_INIT; - backend->active = TRUE; - - connssl->connecting_state = ssl_connect_2; - - return CURLE_OK; -} - -static CURLcode bearssl_run_until(struct connectdata *conn, int sockindex, - unsigned target) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - curl_socket_t sockfd = conn->sock[sockindex]; - unsigned state; - unsigned char *buf; - size_t len; - ssize_t ret; - int err; - - for(;;) { - state = br_ssl_engine_current_state(&backend->ctx.eng); - if(state & BR_SSL_CLOSED) { - err = br_ssl_engine_last_error(&backend->ctx.eng); - switch(err) { - case BR_ERR_OK: - /* TLS close notify */ - if(connssl->state != ssl_connection_complete) { - failf(data, "SSL: connection closed during handshake"); - return CURLE_SSL_CONNECT_ERROR; - } - return CURLE_OK; - case BR_ERR_X509_EXPIRED: - failf(data, "SSL: X.509 verification: " - "certificate is expired or not yet valid"); - return CURLE_PEER_FAILED_VERIFICATION; - case BR_ERR_X509_BAD_SERVER_NAME: - failf(data, "SSL: X.509 verification: " - "expected server name was not found in the chain"); - return CURLE_PEER_FAILED_VERIFICATION; - case BR_ERR_X509_NOT_TRUSTED: - failf(data, "SSL: X.509 verification: " - "chain could not be linked to a trust anchor"); - return CURLE_PEER_FAILED_VERIFICATION; - } - /* X.509 errors are documented to have the range 32..63 */ - if(err >= 32 && err < 64) - return CURLE_PEER_FAILED_VERIFICATION; - return CURLE_SSL_CONNECT_ERROR; - } - if(state & target) - return CURLE_OK; - if(state & BR_SSL_SENDREC) { - buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len); - ret = swrite(sockfd, buf, len); - if(ret == -1) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { - if(connssl->state != ssl_connection_complete) - connssl->connecting_state = ssl_connect_2_writing; - return CURLE_AGAIN; - } - return CURLE_WRITE_ERROR; - } - br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret); - } - else if(state & BR_SSL_RECVREC) { - buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len); - ret = sread(sockfd, buf, len); - if(ret == 0) { - failf(data, "SSL: EOF without close notify"); - return CURLE_READ_ERROR; - } - if(ret == -1) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { - if(connssl->state != ssl_connection_complete) - connssl->connecting_state = ssl_connect_2_reading; - return CURLE_AGAIN; - } - return CURLE_READ_ERROR; - } - br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret); - } - } -} - -static CURLcode bearssl_connect_step2(struct connectdata *conn, int sockindex) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - CURLcode ret; - - ret = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP | BR_SSL_RECVAPP); - if(ret == CURLE_AGAIN) - return CURLE_OK; - if(ret == CURLE_OK) { - if(br_ssl_engine_current_state(&backend->ctx.eng) == BR_SSL_CLOSED) { - failf(data, "SSL: connection closed during handshake"); - return CURLE_SSL_CONNECT_ERROR; - } - connssl->connecting_state = ssl_connect_3; - } - return ret; -} - -static CURLcode bearssl_connect_step3(struct connectdata *conn, int sockindex) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - CURLcode ret; - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - - if(conn->bits.tls_enable_alpn) { - const char *protocol; - - protocol = br_ssl_engine_get_selected_protocol(&backend->ctx.eng); - if(protocol) { - infof(data, "ALPN, server accepted to use %s\n", protocol); - -#ifdef USE_NGHTTP2 - if(!strcmp(protocol, NGHTTP2_PROTO_VERSION_ID)) - conn->negnpn = CURL_HTTP_VERSION_2; - else -#endif - if(!strcmp(protocol, ALPN_HTTP_1_1)) - conn->negnpn = CURL_HTTP_VERSION_1_1; - else - infof(data, "ALPN, unrecognized protocol %s\n", protocol); - Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); - } - else - infof(data, "ALPN, server did not agree to a protocol\n"); - } - - if(SSL_SET_OPTION(primary.sessionid)) { - bool incache; - void *oldsession; - br_ssl_session_parameters *session; - - session = malloc(sizeof(*session)); - if(!session) - return CURLE_OUT_OF_MEMORY; - br_ssl_engine_get_session_parameters(&backend->ctx.eng, session); - Curl_ssl_sessionid_lock(conn); - incache = !(Curl_ssl_getsessionid(conn, &oldsession, NULL, sockindex)); - if(incache) - Curl_ssl_delsessionid(conn, oldsession); - ret = Curl_ssl_addsessionid(conn, session, 0, sockindex); - Curl_ssl_sessionid_unlock(conn); - if(ret) { - free(session); - return CURLE_OUT_OF_MEMORY; - } - } - - connssl->connecting_state = ssl_connect_done; - - return CURLE_OK; -} - -static ssize_t bearssl_send(struct connectdata *conn, int sockindex, - const void *buf, size_t len, CURLcode *err) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - unsigned char *app; - size_t applen; - - for(;;) { - *err = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP); - if (*err != CURLE_OK) - return -1; - app = br_ssl_engine_sendapp_buf(&backend->ctx.eng, &applen); - if(!app) { - failf(data, "SSL: connection closed during write"); - *err = CURLE_SEND_ERROR; - return -1; - } - if(backend->pending_write) { - applen = backend->pending_write; - backend->pending_write = 0; - return applen; - } - if(applen > len) - applen = len; - memcpy(app, buf, applen); - br_ssl_engine_sendapp_ack(&backend->ctx.eng, applen); - br_ssl_engine_flush(&backend->ctx.eng, 0); - backend->pending_write = applen; - } -} - -static ssize_t bearssl_recv(struct connectdata *conn, int sockindex, - char *buf, size_t len, CURLcode *err) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - unsigned char *app; - size_t applen; - - *err = bearssl_run_until(conn, sockindex, BR_SSL_RECVAPP); - if(*err != CURLE_OK) - return -1; - app = br_ssl_engine_recvapp_buf(&backend->ctx.eng, &applen); - if(!app) - return 0; - if(applen > len) - applen = len; - memcpy(buf, app, applen); - br_ssl_engine_recvapp_ack(&backend->ctx.eng, applen); - - return applen; -} - -static CURLcode bearssl_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - CURLcode ret; - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - timediff_t timeout_ms; - int what; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - if(ssl_connect_1 == connssl->connecting_state) { - ret = bearssl_connect_step1(conn, sockindex); - if(ret) - return ret; - } - - while(ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - - curl_socket_t writefd = ssl_connect_2_writing == - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading == - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - - what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, - nonblocking?0:timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) { - *done = FALSE; - return CURLE_OK; - } - else { - /* timeout */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - /* Run transaction, and return to the caller if it failed or if this - * connection is done nonblocking and this loop would execute again. This - * permits the owner of a multi handle to abort a connection attempt - * before step2 has completed while ensuring that a client using select() - * or epoll() will always have a valid fdset to wait on. - */ - ret = bearssl_connect_step2(conn, sockindex); - if(ret || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return ret; - } - - if(ssl_connect_3 == connssl->connecting_state) { - ret = bearssl_connect_step3(conn, sockindex); - if(ret) - return ret; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = bearssl_recv; - conn->send[sockindex] = bearssl_send; - *done = TRUE; - } - else - *done = FALSE; - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - -static size_t Curl_bearssl_version(char *buffer, size_t size) -{ - return msnprintf(buffer, size, "BearSSL"); -} - -static bool Curl_bearssl_data_pending(const struct connectdata *conn, - int connindex) -{ - const struct ssl_connect_data *connssl = &conn->ssl[connindex]; - struct ssl_backend_data *backend = connssl->backend; - return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP; -} - -static CURLcode Curl_bearssl_random(struct Curl_easy *data UNUSED_PARAM, - unsigned char *entropy, size_t length) -{ - static br_hmac_drbg_context ctx; - static bool seeded = FALSE; - - if(!seeded) { - br_prng_seeder seeder; - - br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0); - seeder = br_prng_seeder_system(NULL); - if(!seeder || !seeder(&ctx.vtable)) - return CURLE_FAILED_INIT; - seeded = TRUE; - } - br_hmac_drbg_generate(&ctx, entropy, length); - - return CURLE_OK; -} - -static CURLcode Curl_bearssl_connect(struct connectdata *conn, int sockindex) -{ - CURLcode ret; - bool done = FALSE; - - ret = bearssl_connect_common(conn, sockindex, FALSE, &done); - if(ret) - return ret; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -static CURLcode Curl_bearssl_connect_nonblocking(struct connectdata *conn, - int sockindex, bool *done) -{ - return bearssl_connect_common(conn, sockindex, TRUE, done); -} - -static void *Curl_bearssl_get_internals(struct ssl_connect_data *connssl, - CURLINFO info UNUSED_PARAM) -{ - struct ssl_backend_data *backend = connssl->backend; - return &backend->ctx; -} - -static void Curl_bearssl_close(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - size_t i; - - if(backend->active) { - br_ssl_engine_close(&backend->ctx.eng); - (void)bearssl_run_until(conn, sockindex, BR_SSL_CLOSED); - } - for(i = 0; i < backend->anchors_len; ++i) - free(backend->anchors[i].dn.data); - free(backend->anchors); -} - -static void Curl_bearssl_session_free(void *ptr) -{ - free(ptr); -} - -static CURLcode Curl_bearssl_md5sum(unsigned char *input, - size_t inputlen, - unsigned char *md5sum, - size_t md5len UNUSED_PARAM) -{ - br_md5_context ctx; - - br_md5_init(&ctx); - br_md5_update(&ctx, input, inputlen); - br_md5_out(&ctx, md5sum); - return CURLE_OK; -} - -static CURLcode Curl_bearssl_sha256sum(const unsigned char *input, - size_t inputlen, - unsigned char *sha256sum, - size_t sha256len UNUSED_PARAM) -{ - br_sha256_context ctx; - - br_sha256_init(&ctx); - br_sha256_update(&ctx, input, inputlen); - br_sha256_out(&ctx, sha256sum); - return CURLE_OK; -} - -const struct Curl_ssl Curl_ssl_bearssl = { - { CURLSSLBACKEND_BEARSSL, "bearssl" }, - 0, - sizeof(struct ssl_backend_data), - - Curl_none_init, - Curl_none_cleanup, - Curl_bearssl_version, - Curl_none_check_cxn, - Curl_none_shutdown, - Curl_bearssl_data_pending, - Curl_bearssl_random, - Curl_none_cert_status_request, - Curl_bearssl_connect, - Curl_bearssl_connect_nonblocking, - Curl_bearssl_get_internals, - Curl_bearssl_close, - Curl_none_close_all, - Curl_bearssl_session_free, - Curl_none_set_engine, - Curl_none_set_engine_default, - Curl_none_engines_list, - Curl_none_false_start, - Curl_bearssl_md5sum, - Curl_bearssl_sha256sum -}; - -#endif /* USE_BEARSSL */ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019 - 2020, Michael Forney, <mforney@mforney.org> + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_BEARSSL + +#include <bearssl.h> + +#include "bearssl.h" +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "connect.h" +#include "select.h" +#include "multiif.h" +#include "curl_printf.h" +#include "curl_memory.h" + +struct x509_context { + const br_x509_class *vtable; + br_x509_minimal_context minimal; + bool verifyhost; + bool verifypeer; +}; + +struct ssl_backend_data { + br_ssl_client_context ctx; + struct x509_context x509; + unsigned char buf[BR_SSL_BUFSIZE_BIDI]; + br_x509_trust_anchor *anchors; + size_t anchors_len; + const char *protocols[2]; + /* SSL client context is active */ + bool active; + /* size of pending write, yet to be flushed */ + size_t pending_write; +}; + +struct cafile_parser { + CURLcode err; + bool in_cert; + br_x509_decoder_context xc; + /* array of trust anchors loaded from CAfile */ + br_x509_trust_anchor *anchors; + size_t anchors_len; + /* buffer for DN data */ + unsigned char dn[1024]; + size_t dn_len; +}; + +static void append_dn(void *ctx, const void *buf, size_t len) +{ + struct cafile_parser *ca = ctx; + + if(ca->err != CURLE_OK || !ca->in_cert) + return; + if(sizeof(ca->dn) - ca->dn_len < len) { + ca->err = CURLE_FAILED_INIT; + return; + } + memcpy(ca->dn + ca->dn_len, buf, len); + ca->dn_len += len; +} + +static void x509_push(void *ctx, const void *buf, size_t len) +{ + struct cafile_parser *ca = ctx; + + if(ca->in_cert) + br_x509_decoder_push(&ca->xc, buf, len); +} + +static CURLcode load_cafile(const char *path, br_x509_trust_anchor **anchors, + size_t *anchors_len) +{ + struct cafile_parser ca; + br_pem_decoder_context pc; + br_x509_trust_anchor *ta; + size_t ta_size; + br_x509_trust_anchor *new_anchors; + size_t new_anchors_len; + br_x509_pkey *pkey; + FILE *fp; + unsigned char buf[BUFSIZ], *p; + const char *name; + size_t n, i, pushed; + + fp = fopen(path, "rb"); + if(!fp) + return CURLE_SSL_CACERT_BADFILE; + + ca.err = CURLE_OK; + ca.in_cert = FALSE; + ca.anchors = NULL; + ca.anchors_len = 0; + br_pem_decoder_init(&pc); + br_pem_decoder_setdest(&pc, x509_push, &ca); + for(;;) { + n = fread(buf, 1, sizeof(buf), fp); + if(n == 0) + break; + p = buf; + while(n) { + pushed = br_pem_decoder_push(&pc, p, n); + if(ca.err) + goto fail; + p += pushed; + n -= pushed; + + switch(br_pem_decoder_event(&pc)) { + case 0: + break; + case BR_PEM_BEGIN_OBJ: + name = br_pem_decoder_name(&pc); + if(strcmp(name, "CERTIFICATE") && strcmp(name, "X509 CERTIFICATE")) + break; + br_x509_decoder_init(&ca.xc, append_dn, &ca); + if(ca.anchors_len == SIZE_MAX / sizeof(ca.anchors[0])) { + ca.err = CURLE_OUT_OF_MEMORY; + goto fail; + } + new_anchors_len = ca.anchors_len + 1; + new_anchors = realloc(ca.anchors, + new_anchors_len * sizeof(ca.anchors[0])); + if(!new_anchors) { + ca.err = CURLE_OUT_OF_MEMORY; + goto fail; + } + ca.anchors = new_anchors; + ca.anchors_len = new_anchors_len; + ca.in_cert = TRUE; + ca.dn_len = 0; + ta = &ca.anchors[ca.anchors_len - 1]; + ta->dn.data = NULL; + break; + case BR_PEM_END_OBJ: + if(!ca.in_cert) + break; + ca.in_cert = FALSE; + if(br_x509_decoder_last_error(&ca.xc)) { + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + ta->flags = 0; + if(br_x509_decoder_isCA(&ca.xc)) + ta->flags |= BR_X509_TA_CA; + pkey = br_x509_decoder_get_pkey(&ca.xc); + if(!pkey) { + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + ta->pkey = *pkey; + + /* calculate space needed for trust anchor data */ + ta_size = ca.dn_len; + switch(pkey->key_type) { + case BR_KEYTYPE_RSA: + ta_size += pkey->key.rsa.nlen + pkey->key.rsa.elen; + break; + case BR_KEYTYPE_EC: + ta_size += pkey->key.ec.qlen; + break; + default: + ca.err = CURLE_FAILED_INIT; + goto fail; + } + + /* fill in trust anchor DN and public key data */ + ta->dn.data = malloc(ta_size); + if(!ta->dn.data) { + ca.err = CURLE_OUT_OF_MEMORY; + goto fail; + } + memcpy(ta->dn.data, ca.dn, ca.dn_len); + ta->dn.len = ca.dn_len; + switch(pkey->key_type) { + case BR_KEYTYPE_RSA: + ta->pkey.key.rsa.n = ta->dn.data + ta->dn.len; + memcpy(ta->pkey.key.rsa.n, pkey->key.rsa.n, pkey->key.rsa.nlen); + ta->pkey.key.rsa.e = ta->pkey.key.rsa.n + ta->pkey.key.rsa.nlen; + memcpy(ta->pkey.key.rsa.e, pkey->key.rsa.e, pkey->key.rsa.elen); + break; + case BR_KEYTYPE_EC: + ta->pkey.key.ec.q = ta->dn.data + ta->dn.len; + memcpy(ta->pkey.key.ec.q, pkey->key.ec.q, pkey->key.ec.qlen); + break; + } + break; + default: + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + } + } + if(ferror(fp)) + ca.err = CURLE_READ_ERROR; + +fail: + fclose(fp); + if(ca.err == CURLE_OK) { + *anchors = ca.anchors; + *anchors_len = ca.anchors_len; + } + else { + for(i = 0; i < ca.anchors_len; ++i) + free(ca.anchors[i].dn.data); + free(ca.anchors); + } + + return ca.err; +} + +static void x509_start_chain(const br_x509_class **ctx, + const char *server_name) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + if(!x509->verifyhost) + server_name = NULL; + x509->minimal.vtable->start_chain(&x509->minimal.vtable, server_name); +} + +static void x509_start_cert(const br_x509_class **ctx, uint32_t length) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + x509->minimal.vtable->start_cert(&x509->minimal.vtable, length); +} + +static void x509_append(const br_x509_class **ctx, const unsigned char *buf, + size_t len) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + x509->minimal.vtable->append(&x509->minimal.vtable, buf, len); +} + +static void x509_end_cert(const br_x509_class **ctx) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + x509->minimal.vtable->end_cert(&x509->minimal.vtable); +} + +static unsigned x509_end_chain(const br_x509_class **ctx) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + unsigned err; + + err = x509->minimal.vtable->end_chain(&x509->minimal.vtable); + if(err && !x509->verifypeer) { + /* ignore any X.509 errors */ + err = BR_ERR_OK; + } + + return err; +} + +static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx, + unsigned *usages) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + return x509->minimal.vtable->get_pkey(&x509->minimal.vtable, usages); +} + +static const br_x509_class x509_vtable = { + sizeof(struct x509_context), + x509_start_chain, + x509_start_cert, + x509_append, + x509_end_cert, + x509_end_chain, + x509_get_pkey +}; + +static CURLcode bearssl_connect_step1(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); +#ifndef CURL_DISABLE_PROXY + const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; +#else + const char *hostname = conn->host.name; +#endif + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const bool verifyhost = SSL_CONN_CONFIG(verifyhost); + CURLcode ret; + unsigned version_min, version_max; +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_SSLv2: + failf(data, "BearSSL does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv3: + failf(data, "BearSSL does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_0: + version_min = BR_TLS10; + version_max = BR_TLS10; + break; + case CURL_SSLVERSION_TLSv1_1: + version_min = BR_TLS11; + version_max = BR_TLS11; + break; + case CURL_SSLVERSION_TLSv1_2: + version_min = BR_TLS12; + version_max = BR_TLS12; + break; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + version_min = BR_TLS10; + version_max = BR_TLS12; + break; + default: + failf(data, "BearSSL: unknown CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(ssl_cafile) { + ret = load_cafile(ssl_cafile, &backend->anchors, &backend->anchors_len); + if(ret != CURLE_OK) { + if(verifypeer) { + failf(data, "error setting certificate verify locations:\n" + " CAfile: %s\n", ssl_cafile); + return ret; + } + infof(data, "error setting certificate verify locations," + " continuing anyway:\n"); + } + } + + /* initialize SSL context */ + br_ssl_client_init_full(&backend->ctx, &backend->x509.minimal, + backend->anchors, backend->anchors_len); + br_ssl_engine_set_versions(&backend->ctx.eng, version_min, version_max); + br_ssl_engine_set_buffer(&backend->ctx.eng, backend->buf, + sizeof(backend->buf), 1); + + /* initialize X.509 context */ + backend->x509.vtable = &x509_vtable; + backend->x509.verifypeer = verifypeer; + backend->x509.verifyhost = verifyhost; + br_ssl_engine_set_x509(&backend->ctx.eng, &backend->x509.vtable); + + if(SSL_SET_OPTION(primary.sessionid)) { + void *session; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &session, NULL, sockindex)) { + br_ssl_engine_set_session_parameters(&backend->ctx.eng, session); + infof(data, "BearSSL: re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + if(conn->bits.tls_enable_alpn) { + int cur = 0; + + /* NOTE: when adding more protocols here, increase the size of the + * protocols array in `struct ssl_backend_data`. + */ + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2 +#ifndef CURL_DISABLE_PROXY + && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) +#endif + ) { + backend->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + backend->protocols[cur++] = ALPN_HTTP_1_1; + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + br_ssl_engine_set_protocol_names(&backend->ctx.eng, + backend->protocols, cur); + } + + if((1 == Curl_inet_pton(AF_INET, hostname, &addr)) +#ifdef ENABLE_IPV6 + || (1 == Curl_inet_pton(AF_INET6, hostname, &addr)) +#endif + ) { + if(verifyhost) { + failf(data, "BearSSL: " + "host verification of IP address is not supported"); + return CURLE_PEER_FAILED_VERIFICATION; + } + hostname = NULL; + } + + if(!br_ssl_client_reset(&backend->ctx, hostname, 0)) + return CURLE_FAILED_INIT; + backend->active = TRUE; + + connssl->connecting_state = ssl_connect_2; + + return CURLE_OK; +} + +static CURLcode bearssl_run_until(struct connectdata *conn, int sockindex, + unsigned target) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + curl_socket_t sockfd = conn->sock[sockindex]; + unsigned state; + unsigned char *buf; + size_t len; + ssize_t ret; + int err; + + for(;;) { + state = br_ssl_engine_current_state(&backend->ctx.eng); + if(state & BR_SSL_CLOSED) { + err = br_ssl_engine_last_error(&backend->ctx.eng); + switch(err) { + case BR_ERR_OK: + /* TLS close notify */ + if(connssl->state != ssl_connection_complete) { + failf(data, "SSL: connection closed during handshake"); + return CURLE_SSL_CONNECT_ERROR; + } + return CURLE_OK; + case BR_ERR_X509_EXPIRED: + failf(data, "SSL: X.509 verification: " + "certificate is expired or not yet valid"); + return CURLE_PEER_FAILED_VERIFICATION; + case BR_ERR_X509_BAD_SERVER_NAME: + failf(data, "SSL: X.509 verification: " + "expected server name was not found in the chain"); + return CURLE_PEER_FAILED_VERIFICATION; + case BR_ERR_X509_NOT_TRUSTED: + failf(data, "SSL: X.509 verification: " + "chain could not be linked to a trust anchor"); + return CURLE_PEER_FAILED_VERIFICATION; + } + /* X.509 errors are documented to have the range 32..63 */ + if(err >= 32 && err < 64) + return CURLE_PEER_FAILED_VERIFICATION; + return CURLE_SSL_CONNECT_ERROR; + } + if(state & target) + return CURLE_OK; + if(state & BR_SSL_SENDREC) { + buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len); + ret = swrite(sockfd, buf, len); + if(ret == -1) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(connssl->state != ssl_connection_complete) + connssl->connecting_state = ssl_connect_2_writing; + return CURLE_AGAIN; + } + return CURLE_WRITE_ERROR; + } + br_ssl_engine_sendrec_ack(&backend->ctx.eng, ret); + } + else if(state & BR_SSL_RECVREC) { + buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len); + ret = sread(sockfd, buf, len); + if(ret == 0) { + failf(data, "SSL: EOF without close notify"); + return CURLE_READ_ERROR; + } + if(ret == -1) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(connssl->state != ssl_connection_complete) + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_AGAIN; + } + return CURLE_READ_ERROR; + } + br_ssl_engine_recvrec_ack(&backend->ctx.eng, ret); + } + } +} + +static CURLcode bearssl_connect_step2(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + CURLcode ret; + + ret = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP | BR_SSL_RECVAPP); + if(ret == CURLE_AGAIN) + return CURLE_OK; + if(ret == CURLE_OK) { + if(br_ssl_engine_current_state(&backend->ctx.eng) == BR_SSL_CLOSED) { + failf(data, "SSL: connection closed during handshake"); + return CURLE_SSL_CONNECT_ERROR; + } + connssl->connecting_state = ssl_connect_3; + } + return ret; +} + +static CURLcode bearssl_connect_step3(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + CURLcode ret; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + if(conn->bits.tls_enable_alpn) { + const char *protocol; + + protocol = br_ssl_engine_get_selected_protocol(&backend->ctx.eng); + if(protocol) { + infof(data, "ALPN, server accepted to use %s\n", protocol); + +#ifdef USE_NGHTTP2 + if(!strcmp(protocol, NGHTTP2_PROTO_VERSION_ID)) + conn->negnpn = CURL_HTTP_VERSION_2; + else +#endif + if(!strcmp(protocol, ALPN_HTTP_1_1)) + conn->negnpn = CURL_HTTP_VERSION_1_1; + else + infof(data, "ALPN, unrecognized protocol %s\n", protocol); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + } + + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + void *oldsession; + br_ssl_session_parameters *session; + + session = malloc(sizeof(*session)); + if(!session) + return CURLE_OUT_OF_MEMORY; + br_ssl_engine_get_session_parameters(&backend->ctx.eng, session); + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, &oldsession, NULL, sockindex)); + if(incache) + Curl_ssl_delsessionid(conn, oldsession); + ret = Curl_ssl_addsessionid(conn, session, 0, sockindex); + Curl_ssl_sessionid_unlock(conn); + if(ret) { + free(session); + return CURLE_OUT_OF_MEMORY; + } + } + + connssl->connecting_state = ssl_connect_done; + + return CURLE_OK; +} + +static ssize_t bearssl_send(struct connectdata *conn, int sockindex, + const void *buf, size_t len, CURLcode *err) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + unsigned char *app; + size_t applen; + + for(;;) { + *err = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP); + if (*err != CURLE_OK) + return -1; + app = br_ssl_engine_sendapp_buf(&backend->ctx.eng, &applen); + if(!app) { + failf(data, "SSL: connection closed during write"); + *err = CURLE_SEND_ERROR; + return -1; + } + if(backend->pending_write) { + applen = backend->pending_write; + backend->pending_write = 0; + return applen; + } + if(applen > len) + applen = len; + memcpy(app, buf, applen); + br_ssl_engine_sendapp_ack(&backend->ctx.eng, applen); + br_ssl_engine_flush(&backend->ctx.eng, 0); + backend->pending_write = applen; + } +} + +static ssize_t bearssl_recv(struct connectdata *conn, int sockindex, + char *buf, size_t len, CURLcode *err) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + unsigned char *app; + size_t applen; + + *err = bearssl_run_until(conn, sockindex, BR_SSL_RECVAPP); + if(*err != CURLE_OK) + return -1; + app = br_ssl_engine_recvapp_buf(&backend->ctx.eng, &applen); + if(!app) + return 0; + if(applen > len) + applen = len; + memcpy(buf, app, applen); + br_ssl_engine_recvapp_ack(&backend->ctx.eng, applen); + + return applen; +} + +static CURLcode bearssl_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode ret; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + timediff_t timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + ret = bearssl_connect_step1(conn, sockindex); + if(ret) + return ret; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if this + * connection is done nonblocking and this loop would execute again. This + * permits the owner of a multi handle to abort a connection attempt + * before step2 has completed while ensuring that a client using select() + * or epoll() will always have a valid fdset to wait on. + */ + ret = bearssl_connect_step2(conn, sockindex); + if(ret || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return ret; + } + + if(ssl_connect_3 == connssl->connecting_state) { + ret = bearssl_connect_step3(conn, sockindex); + if(ret) + return ret; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = bearssl_recv; + conn->send[sockindex] = bearssl_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static size_t Curl_bearssl_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "BearSSL"); +} + +static bool Curl_bearssl_data_pending(const struct connectdata *conn, + int connindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; + struct ssl_backend_data *backend = connssl->backend; + return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP; +} + +static CURLcode Curl_bearssl_random(struct Curl_easy *data UNUSED_PARAM, + unsigned char *entropy, size_t length) +{ + static br_hmac_drbg_context ctx; + static bool seeded = FALSE; + + if(!seeded) { + br_prng_seeder seeder; + + br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0); + seeder = br_prng_seeder_system(NULL); + if(!seeder || !seeder(&ctx.vtable)) + return CURLE_FAILED_INIT; + seeded = TRUE; + } + br_hmac_drbg_generate(&ctx, entropy, length); + + return CURLE_OK; +} + +static CURLcode Curl_bearssl_connect(struct connectdata *conn, int sockindex) +{ + CURLcode ret; + bool done = FALSE; + + ret = bearssl_connect_common(conn, sockindex, FALSE, &done); + if(ret) + return ret; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static CURLcode Curl_bearssl_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return bearssl_connect_common(conn, sockindex, TRUE, done); +} + +static void *Curl_bearssl_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + struct ssl_backend_data *backend = connssl->backend; + return &backend->ctx; +} + +static void Curl_bearssl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + size_t i; + + if(backend->active) { + br_ssl_engine_close(&backend->ctx.eng); + (void)bearssl_run_until(conn, sockindex, BR_SSL_CLOSED); + } + for(i = 0; i < backend->anchors_len; ++i) + free(backend->anchors[i].dn.data); + free(backend->anchors); +} + +static void Curl_bearssl_session_free(void *ptr) +{ + free(ptr); +} + +static CURLcode Curl_bearssl_md5sum(unsigned char *input, + size_t inputlen, + unsigned char *md5sum, + size_t md5len UNUSED_PARAM) +{ + br_md5_context ctx; + + br_md5_init(&ctx); + br_md5_update(&ctx, input, inputlen); + br_md5_out(&ctx, md5sum); + return CURLE_OK; +} + +static CURLcode Curl_bearssl_sha256sum(const unsigned char *input, + size_t inputlen, + unsigned char *sha256sum, + size_t sha256len UNUSED_PARAM) +{ + br_sha256_context ctx; + + br_sha256_init(&ctx); + br_sha256_update(&ctx, input, inputlen); + br_sha256_out(&ctx, sha256sum); + return CURLE_OK; +} + +const struct Curl_ssl Curl_ssl_bearssl = { + { CURLSSLBACKEND_BEARSSL, "bearssl" }, + 0, + sizeof(struct ssl_backend_data), + + Curl_none_init, + Curl_none_cleanup, + Curl_bearssl_version, + Curl_none_check_cxn, + Curl_none_shutdown, + Curl_bearssl_data_pending, + Curl_bearssl_random, + Curl_none_cert_status_request, + Curl_bearssl_connect, + Curl_bearssl_connect_nonblocking, + Curl_bearssl_get_internals, + Curl_bearssl_close, + Curl_none_close_all, + Curl_bearssl_session_free, + Curl_none_set_engine, + Curl_none_set_engine_default, + Curl_none_engines_list, + Curl_none_false_start, + Curl_bearssl_md5sum, + Curl_bearssl_sha256sum +}; + +#endif /* USE_BEARSSL */ diff --git a/contrib/libs/curl/lib/vtls/bearssl.h b/contrib/libs/curl/lib/vtls/bearssl.h index d72b7d0e26..182c13d73f 100644 --- a/contrib/libs/curl/lib/vtls/bearssl.h +++ b/contrib/libs/curl/lib/vtls/bearssl.h @@ -1,32 +1,32 @@ -#ifndef HEADER_CURL_BEARSSL_H -#define HEADER_CURL_BEARSSL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2019 - 2020, Michael Forney, <mforney@mforney.org> - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_BEARSSL - -extern const struct Curl_ssl Curl_ssl_bearssl; - -#endif /* USE_BEARSSL */ -#endif /* HEADER_CURL_BEARSSL_H */ +#ifndef HEADER_CURL_BEARSSL_H +#define HEADER_CURL_BEARSSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019 - 2020, Michael Forney, <mforney@mforney.org> + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_BEARSSL + +extern const struct Curl_ssl Curl_ssl_bearssl; + +#endif /* USE_BEARSSL */ +#endif /* HEADER_CURL_BEARSSL_H */ diff --git a/contrib/libs/curl/lib/vtls/gskit.c b/contrib/libs/curl/lib/vtls/gskit.c index 17584c750f..e8b53d7e41 100644 --- a/contrib/libs/curl/lib/vtls/gskit.c +++ b/contrib/libs/curl/lib/vtls/gskit.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -26,8 +26,8 @@ #include <gskssl.h> #include <qsoasync.h> -#undef HAVE_SOCKETPAIR /* because the native one isn't good enough */ -#include "socketpair.h" +#undef HAVE_SOCKETPAIR /* because the native one isn't good enough */ +#include "socketpair.h" /* Some symbols are undefined/unsupported on OS400 versions < V7R1. */ #ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST @@ -108,13 +108,13 @@ struct ssl_backend_data { #define BACKEND connssl->backend /* Supported ciphers. */ -struct gskit_cipher { +struct gskit_cipher { const char *name; /* Cipher name. */ const char *gsktoken; /* Corresponding token for GSKit String. */ unsigned int versions; /* SSL version flags. */ -}; +}; -static const struct gskit_cipher ciphertable[] = { +static const struct gskit_cipher ciphertable[] = { { "null-md5", "01", CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, @@ -307,7 +307,7 @@ static CURLcode set_ciphers(struct connectdata *conn, struct Curl_easy *data = conn->data; const char *cipherlist = SSL_CONN_CONFIG(cipher_list); const char *clp; - const struct gskit_cipher *ctp; + const struct gskit_cipher *ctp; int i; int l; bool unsupported; @@ -543,7 +543,7 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex, if(n < conn->sock[sockindex]) n = conn->sock[sockindex]; } - i = Curl_select(n + 1, &fds_read, &fds_write, NULL, 0); + i = Curl_select(n + 1, &fds_read, &fds_write, NULL, 0); if(i < 0) return -1; /* Select error. */ @@ -705,7 +705,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex) int rc; const char * const keyringfile = SSL_CONN_CONFIG(CAfile); const char * const keyringpwd = SSL_SET_OPTION(key_passwd); - const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert); + const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert); const long int ssl_version = SSL_CONN_CONFIG(version); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name: @@ -762,7 +762,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex) /* Establish a pipelining socket pair for SSL over SSL. */ if(conn->proxy_ssl[sockindex].use) { - if(Curl_socketpair(0, 0, 0, sockpair)) + if(Curl_socketpair(0, 0, 0, sockpair)) return CURLE_SSL_CONNECT_ERROR; BACKEND->localfd = sockpair[0]; BACKEND->remotefd = sockpair[1]; @@ -819,7 +819,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex) if(!result) { /* Compute the handshake timeout. Since GSKit granularity is 1 second, we round up the required value. */ - timediff_t timeout = Curl_timeleft(data, NULL, TRUE); + timediff_t timeout = Curl_timeleft(data, NULL, TRUE); if(timeout < 0) result = CURLE_OPERATION_TIMEDOUT; else @@ -932,7 +932,7 @@ static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex, /* Poll or wait for end of SSL asynchronous handshake. */ for(;;) { - timediff_t timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE); + timediff_t timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE); if(timeout_ms < 0) timeout_ms = 0; stmv.tv_sec = timeout_ms / 1000; @@ -1064,7 +1064,7 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex, { struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - timediff_t timeout_ms; + timediff_t timeout_ms; CURLcode result = CURLE_OK; *done = connssl->state == ssl_connection_complete; diff --git a/contrib/libs/curl/lib/vtls/gskit.h b/contrib/libs/curl/lib/vtls/gskit.h index 202df7e07c..4d0dc01c2b 100644 --- a/contrib/libs/curl/lib/vtls/gskit.h +++ b/contrib/libs/curl/lib/vtls/gskit.h @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is diff --git a/contrib/libs/curl/lib/vtls/gtls.c b/contrib/libs/curl/lib/vtls/gtls.c index e848c3f05a..c8465ce5b5 100644 --- a/contrib/libs/curl/lib/vtls/gtls.c +++ b/contrib/libs/curl/lib/vtls/gtls.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -72,8 +72,8 @@ static void tls_log_func(int level, const char *str) #endif static bool gtls_inited = FALSE; -#if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x03010a) -#error "too old GnuTLS version" +#if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x03010a) +#error "too old GnuTLS version" #endif # include <gnutls/ocsp.h> @@ -81,7 +81,7 @@ static bool gtls_inited = FALSE; struct ssl_backend_data { gnutls_session_t session; gnutls_certificate_credentials_t cred; -#ifdef HAVE_GNUTLS_SRP +#ifdef HAVE_GNUTLS_SRP gnutls_srp_client_credentials_t srp_client_cred; #endif }; @@ -207,12 +207,12 @@ static CURLcode handshake(struct connectdata *conn, { struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - gnutls_session_t session = backend->session; + struct ssl_backend_data *backend = connssl->backend; + gnutls_session_t session = backend->session; curl_socket_t sockfd = conn->sock[sockindex]; for(;;) { - timediff_t timeout_ms; + timediff_t timeout_ms; int rc; /* check allowed time left */ @@ -304,7 +304,7 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type) return GNUTLS_X509_FMT_PEM; if(strcasecompare(type, "DER")) return GNUTLS_X509_FMT_DER; - return GNUTLS_X509_FMT_PEM; /* default to PEM */ + return GNUTLS_X509_FMT_PEM; /* default to PEM */ } #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509" @@ -324,54 +324,54 @@ set_ssl_version_min_max(const char **prioritylist, struct connectdata *conn) ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT; } switch(ssl_version | ssl_version_max) { - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.0"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.0:+VERS-TLS1.1"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.1"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.1:+VERS-TLS1.2"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.2"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.3"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2" - ":+VERS-TLS1.3"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.1:+VERS-TLS1.2" - ":+VERS-TLS1.3"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.2" - ":+VERS-TLS1.3"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_DEFAULT: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.2" - ":+VERS-TLS1.3"; - return CURLE_OK; + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.0"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.0:+VERS-TLS1.1"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.1"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.1:+VERS-TLS1.2"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.2"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_TLSv1_3: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.3"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2" + ":+VERS-TLS1.3"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.1:+VERS-TLS1.2" + ":+VERS-TLS1.3"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.2" + ":+VERS-TLS1.3"; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_DEFAULT: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" + "+VERS-TLS1.2" + ":+VERS-TLS1.3"; + return CURLE_OK; } failf(data, "GnuTLS: cannot set ssl protocol"); @@ -384,7 +384,7 @@ gtls_connect_step1(struct connectdata *conn, { struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; unsigned int init_flags; gnutls_session_t session; int rc; @@ -399,8 +399,8 @@ gtls_connect_step1(struct connectdata *conn, #endif const char *prioritylist; const char *err = NULL; - const char * const hostname = SSL_HOST_NAME(); - long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult); + const char * const hostname = SSL_HOST_NAME(); + long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult); if(connssl->state == ssl_connection_complete) /* to make us tolerant against being called more than once for the @@ -410,9 +410,9 @@ gtls_connect_step1(struct connectdata *conn, if(!gtls_inited) Curl_gtls_init(); - /* Initialize certverifyresult to OK */ - *certverifyresult = 0; - + /* Initialize certverifyresult to OK */ + *certverifyresult = 0; + if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { failf(data, "GnuTLS does not support SSLv2"); return CURLE_SSL_CONNECT_ERROR; @@ -421,25 +421,25 @@ gtls_connect_step1(struct connectdata *conn, sni = FALSE; /* SSLv3 has no SNI */ /* allocate a cred struct */ - rc = gnutls_certificate_allocate_credentials(&backend->cred); + rc = gnutls_certificate_allocate_credentials(&backend->cred); if(rc != GNUTLS_E_SUCCESS) { failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc)); return CURLE_SSL_CONNECT_ERROR; } -#ifdef HAVE_GNUTLS_SRP +#ifdef HAVE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username)); rc = gnutls_srp_allocate_client_credentials( - &backend->srp_client_cred); + &backend->srp_client_cred); if(rc != GNUTLS_E_SUCCESS) { failf(data, "gnutls_srp_allocate_client_cred() failed: %s", gnutls_strerror(rc)); return CURLE_OUT_OF_MEMORY; } - rc = gnutls_srp_set_client_credentials(backend->srp_client_cred, + rc = gnutls_srp_set_client_credentials(backend->srp_client_cred, SSL_SET_OPTION(username), SSL_SET_OPTION(password)); if(rc != GNUTLS_E_SUCCESS) { @@ -452,19 +452,19 @@ gtls_connect_step1(struct connectdata *conn, if(SSL_CONN_CONFIG(CAfile)) { /* set the trusted CA cert bundle file */ - gnutls_certificate_set_verify_flags(backend->cred, + gnutls_certificate_set_verify_flags(backend->cred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); - rc = gnutls_certificate_set_x509_trust_file(backend->cred, + rc = gnutls_certificate_set_x509_trust_file(backend->cred, SSL_CONN_CONFIG(CAfile), GNUTLS_X509_FMT_PEM); if(rc < 0) { infof(data, "error reading ca cert file %s (%s)\n", SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc)); - if(SSL_CONN_CONFIG(verifypeer)) { - *certverifyresult = rc; + if(SSL_CONN_CONFIG(verifypeer)) { + *certverifyresult = rc; return CURLE_SSL_CACERT_BADFILE; - } + } } else infof(data, "found %d certificates in %s\n", rc, @@ -473,16 +473,16 @@ gtls_connect_step1(struct connectdata *conn, if(SSL_CONN_CONFIG(CApath)) { /* set the trusted CA cert directory */ - rc = gnutls_certificate_set_x509_trust_dir(backend->cred, + rc = gnutls_certificate_set_x509_trust_dir(backend->cred, SSL_CONN_CONFIG(CApath), GNUTLS_X509_FMT_PEM); if(rc < 0) { infof(data, "error reading ca cert file %s (%s)\n", SSL_CONN_CONFIG(CApath), gnutls_strerror(rc)); - if(SSL_CONN_CONFIG(verifypeer)) { - *certverifyresult = rc; + if(SSL_CONN_CONFIG(verifypeer)) { + *certverifyresult = rc; return CURLE_SSL_CACERT_BADFILE; - } + } } else infof(data, "found %d certificates in %s\n", @@ -493,13 +493,13 @@ gtls_connect_step1(struct connectdata *conn, /* use system ca certificate store as fallback */ if(SSL_CONN_CONFIG(verifypeer) && !(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) { - gnutls_certificate_set_x509_system_trust(backend->cred); + gnutls_certificate_set_x509_system_trust(backend->cred); } #endif if(SSL_SET_OPTION(CRLfile)) { /* set the CRL list file */ - rc = gnutls_certificate_set_x509_crl_file(backend->cred, + rc = gnutls_certificate_set_x509_crl_file(backend->cred, SSL_SET_OPTION(CRLfile), GNUTLS_X509_FMT_PEM); if(rc < 0) { @@ -515,23 +515,23 @@ gtls_connect_step1(struct connectdata *conn, /* Initialize TLS session as a client */ init_flags = GNUTLS_CLIENT; -#if defined(GNUTLS_FORCE_CLIENT_CERT) - init_flags |= GNUTLS_FORCE_CLIENT_CERT; -#endif - +#if defined(GNUTLS_FORCE_CLIENT_CERT) + init_flags |= GNUTLS_FORCE_CLIENT_CERT; +#endif + #if defined(GNUTLS_NO_TICKETS) /* Disable TLS session tickets */ init_flags |= GNUTLS_NO_TICKETS; #endif - rc = gnutls_init(&backend->session, init_flags); + rc = gnutls_init(&backend->session, init_flags); if(rc != GNUTLS_E_SUCCESS) { failf(data, "gnutls_init() failed: %d", rc); return CURLE_SSL_CONNECT_ERROR; } /* convenient assign */ - session = backend->session; + session = backend->session; if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) && #ifdef ENABLE_IPV6 @@ -557,11 +557,11 @@ gtls_connect_step1(struct connectdata *conn, break; case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0" + prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0" #ifdef HAS_TLS13 - ":+VERS-TLS1.3" + ":+VERS-TLS1.3" #endif - ; + ; break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: @@ -581,32 +581,32 @@ gtls_connect_step1(struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } -#ifdef HAVE_GNUTLS_SRP - /* Only add SRP to the cipher list if SRP is requested. Otherwise - * GnuTLS will disable TLS 1.3 support. */ - if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { - size_t len = strlen(prioritylist); - - char *prioritysrp = malloc(len + sizeof(GNUTLS_SRP) + 1); - if(!prioritysrp) - return CURLE_OUT_OF_MEMORY; - strcpy(prioritysrp, prioritylist); - strcpy(prioritysrp + len, ":" GNUTLS_SRP); - - rc = gnutls_priority_set_direct(session, prioritysrp, &err); - free(prioritysrp); - - if((rc == GNUTLS_E_INVALID_REQUEST) && err) { +#ifdef HAVE_GNUTLS_SRP + /* Only add SRP to the cipher list if SRP is requested. Otherwise + * GnuTLS will disable TLS 1.3 support. */ + if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { + size_t len = strlen(prioritylist); + + char *prioritysrp = malloc(len + sizeof(GNUTLS_SRP) + 1); + if(!prioritysrp) + return CURLE_OUT_OF_MEMORY; + strcpy(prioritysrp, prioritylist); + strcpy(prioritysrp + len, ":" GNUTLS_SRP); + + rc = gnutls_priority_set_direct(session, prioritysrp, &err); + free(prioritysrp); + + if((rc == GNUTLS_E_INVALID_REQUEST) && err) { infof(data, "This GnuTLS does not support SRP\n"); } } - else { -#endif - rc = gnutls_priority_set_direct(session, prioritylist, &err); -#ifdef HAVE_GNUTLS_SRP - } -#endif - + else { +#endif + rc = gnutls_priority_set_direct(session, prioritylist, &err); +#ifdef HAVE_GNUTLS_SRP + } +#endif + if(rc != GNUTLS_E_SUCCESS) { failf(data, "Error %d setting GnuTLS cipher list starting with %s", rc, err); @@ -618,11 +618,11 @@ gtls_connect_step1(struct connectdata *conn, gnutls_datum_t protocols[2]; #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 -#ifndef CURL_DISABLE_PROXY - && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) -#endif - ) { + if(data->set.httpversion >= CURL_HTTP_VERSION_2 +#ifndef CURL_DISABLE_PROXY + && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) +#endif + ) { protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID; protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN; cur++; @@ -638,7 +638,7 @@ gtls_connect_step1(struct connectdata *conn, gnutls_alpn_set_protocols(session, protocols, cur, 0); } - if(SSL_SET_OPTION(primary.clientcert)) { + if(SSL_SET_OPTION(primary.clientcert)) { if(SSL_SET_OPTION(key_passwd)) { const unsigned int supported_key_encryption_algorithms = GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR | @@ -646,10 +646,10 @@ gtls_connect_step1(struct connectdata *conn, GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 | GNUTLS_PKCS_USE_PBES2_AES_256; rc = gnutls_certificate_set_x509_key_file2( - backend->cred, - SSL_SET_OPTION(primary.clientcert), + backend->cred, + SSL_SET_OPTION(primary.clientcert), SSL_SET_OPTION(key) ? - SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert), + SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert), do_file_type(SSL_SET_OPTION(cert_type)), SSL_SET_OPTION(key_passwd), supported_key_encryption_algorithms); @@ -662,10 +662,10 @@ gtls_connect_step1(struct connectdata *conn, } else { if(gnutls_certificate_set_x509_key_file( - backend->cred, - SSL_SET_OPTION(primary.clientcert), + backend->cred, + SSL_SET_OPTION(primary.clientcert), SSL_SET_OPTION(key) ? - SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert), + SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert), do_file_type(SSL_SET_OPTION(cert_type)) ) != GNUTLS_E_SUCCESS) { failf(data, "error reading X.509 key or certificate file"); @@ -674,11 +674,11 @@ gtls_connect_step1(struct connectdata *conn, } } -#ifdef HAVE_GNUTLS_SRP +#ifdef HAVE_GNUTLS_SRP /* put the credentials to the current session */ if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP, - backend->srp_client_cred); + backend->srp_client_cred); if(rc != GNUTLS_E_SUCCESS) { failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); return CURLE_SSL_CONNECT_ERROR; @@ -688,22 +688,22 @@ gtls_connect_step1(struct connectdata *conn, #endif { rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, - backend->cred); + backend->cred); if(rc != GNUTLS_E_SUCCESS) { failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); return CURLE_SSL_CONNECT_ERROR; } } -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY if(conn->proxy_ssl[sockindex].use) { transport_ptr = conn->proxy_ssl[sockindex].backend->session; gnutls_transport_push = Curl_gtls_push_ssl; gnutls_transport_pull = Curl_gtls_pull_ssl; } - else -#endif - { + else +#endif + { /* file descriptor for the socket */ transport_ptr = &conn->sock[sockindex]; gnutls_transport_push = Curl_gtls_push; @@ -815,15 +815,15 @@ gtls_connect_step3(struct connectdata *conn, unsigned int verify_status = 0; gnutls_x509_crt_t x509_cert, x509_issuer; gnutls_datum_t issuerp; - gnutls_datum_t certfields; - char certname[65] = ""; /* limited to 64 chars by ASN.1 */ + gnutls_datum_t certfields; + char certname[65] = ""; /* limited to 64 chars by ASN.1 */ size_t size; time_t certclock; const char *ptr; struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - gnutls_session_t session = backend->session; + struct ssl_backend_data *backend = connssl->backend; + gnutls_session_t session = backend->session; int rc; gnutls_datum_t proto; CURLcode result = CURLE_OK; @@ -832,8 +832,8 @@ gtls_connect_step3(struct connectdata *conn, unsigned int bits; gnutls_protocol_t version = gnutls_protocol_get_version(session); #endif - const char * const hostname = SSL_HOST_NAME(); - long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult); + const char * const hostname = SSL_HOST_NAME(); + long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult); /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session), @@ -854,7 +854,7 @@ gtls_connect_step3(struct connectdata *conn, if(SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost) || SSL_SET_OPTION(issuercert)) { -#ifdef HAVE_GNUTLS_SRP +#ifdef HAVE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP && SSL_SET_OPTION(username) != NULL && !SSL_CONN_CONFIG(verifypeer) @@ -865,9 +865,9 @@ gtls_connect_step3(struct connectdata *conn, else { #endif failf(data, "failed to get server cert"); - *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND; + *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND; return CURLE_PEER_FAILED_VERIFICATION; -#ifdef HAVE_GNUTLS_SRP +#ifdef HAVE_GNUTLS_SRP } #endif } @@ -902,12 +902,12 @@ gtls_connect_step3(struct connectdata *conn, rc = gnutls_certificate_verify_peers2(session, &verify_status); if(rc < 0) { failf(data, "server cert verify failed: %d", rc); - *certverifyresult = rc; + *certverifyresult = rc; return CURLE_SSL_CONNECT_ERROR; } - *certverifyresult = verify_status; - + *certverifyresult = verify_status; + /* verify_status is a bitmask of gnutls_certificate_status bits */ if(verify_status & GNUTLS_CERT_INVALID) { if(SSL_CONN_CONFIG(verifypeer)) { @@ -1054,11 +1054,11 @@ gtls_connect_step3(struct connectdata *conn, SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); } - size = sizeof(certname); + size = sizeof(certname); rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME, 0, /* the first and only one */ FALSE, - certname, + certname, &size); if(rc) { infof(data, "error fetching CN from cert:%s\n", @@ -1116,16 +1116,16 @@ gtls_connect_step3(struct connectdata *conn, if(!rc) { if(SSL_CONN_CONFIG(verifyhost)) { failf(data, "SSL: certificate subject name (%s) does not match " - "target host name '%s'", certname, SSL_HOST_DISPNAME()); + "target host name '%s'", certname, SSL_HOST_DISPNAME()); gnutls_x509_crt_deinit(x509_cert); return CURLE_PEER_FAILED_VERIFICATION; } else infof(data, "\t common name: %s (does not match '%s')\n", - certname, SSL_HOST_DISPNAME()); + certname, SSL_HOST_DISPNAME()); } else - infof(data, "\t common name: %s (matched)\n", certname); + infof(data, "\t common name: %s (matched)\n", certname); /* Check for time-based validity */ certclock = gnutls_x509_crt_get_expiration_time(x509_cert); @@ -1133,7 +1133,7 @@ gtls_connect_step3(struct connectdata *conn, if(certclock == (time_t)-1) { if(SSL_CONN_CONFIG(verifypeer)) { failf(data, "server cert expiration date verify failed"); - *certverifyresult = GNUTLS_CERT_EXPIRED; + *certverifyresult = GNUTLS_CERT_EXPIRED; gnutls_x509_crt_deinit(x509_cert); return CURLE_SSL_CONNECT_ERROR; } @@ -1144,7 +1144,7 @@ gtls_connect_step3(struct connectdata *conn, if(certclock < time(NULL)) { if(SSL_CONN_CONFIG(verifypeer)) { failf(data, "server certificate expiration date has passed."); - *certverifyresult = GNUTLS_CERT_EXPIRED; + *certverifyresult = GNUTLS_CERT_EXPIRED; gnutls_x509_crt_deinit(x509_cert); return CURLE_PEER_FAILED_VERIFICATION; } @@ -1160,7 +1160,7 @@ gtls_connect_step3(struct connectdata *conn, if(certclock == (time_t)-1) { if(SSL_CONN_CONFIG(verifypeer)) { failf(data, "server cert activation date verify failed"); - *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; + *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; gnutls_x509_crt_deinit(x509_cert); return CURLE_SSL_CONNECT_ERROR; } @@ -1171,7 +1171,7 @@ gtls_connect_step3(struct connectdata *conn, if(certclock > time(NULL)) { if(SSL_CONN_CONFIG(verifypeer)) { failf(data, "server certificate not activated yet."); - *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; + *certverifyresult = GNUTLS_CERT_NOT_ACTIVATED; gnutls_x509_crt_deinit(x509_cert); return CURLE_PEER_FAILED_VERIFICATION; } @@ -1214,29 +1214,29 @@ gtls_connect_step3(struct connectdata *conn, gnutls_x509_crt_get_version(x509_cert)); - rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields); - if(rc) - infof(data, "Failed to get certificate name\n"); - else { - infof(data, "\t subject: %s\n", certfields.data); - - certclock = gnutls_x509_crt_get_activation_time(x509_cert); - showtime(data, "start date", certclock); - - certclock = gnutls_x509_crt_get_expiration_time(x509_cert); - showtime(data, "expire date", certclock); - - gnutls_free(certfields.data); - } - - rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields); - if(rc) - infof(data, "Failed to get certificate issuer\n"); - else { - infof(data, "\t issuer: %s\n", certfields.data); - - gnutls_free(certfields.data); - } + rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields); + if(rc) + infof(data, "Failed to get certificate name\n"); + else { + infof(data, "\t subject: %s\n", certfields.data); + + certclock = gnutls_x509_crt_get_activation_time(x509_cert); + showtime(data, "start date", certclock); + + certclock = gnutls_x509_crt_get_expiration_time(x509_cert); + showtime(data, "expire date", certclock); + + gnutls_free(certfields.data); + } + + rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields); + if(rc) + infof(data, "Failed to get certificate issuer\n"); + else { + infof(data, "\t issuer: %s\n", certfields.data); + + gnutls_free(certfields.data); + } #endif gnutls_x509_crt_deinit(x509_cert); @@ -1383,18 +1383,18 @@ static bool Curl_gtls_data_pending(const struct connectdata *conn, { const struct ssl_connect_data *connssl = &conn->ssl[connindex]; bool res = FALSE; - struct ssl_backend_data *backend = connssl->backend; - if(backend->session && - 0 != gnutls_record_check_pending(backend->session)) + struct ssl_backend_data *backend = connssl->backend; + if(backend->session && + 0 != gnutls_record_check_pending(backend->session)) res = TRUE; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY connssl = &conn->proxy_ssl[connindex]; - backend = connssl->backend; - if(backend->session && - 0 != gnutls_record_check_pending(backend->session)) + backend = connssl->backend; + if(backend->session && + 0 != gnutls_record_check_pending(backend->session)) res = TRUE; -#endif +#endif return res; } @@ -1406,8 +1406,8 @@ static ssize_t gtls_send(struct connectdata *conn, CURLcode *curlcode) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - ssize_t rc = gnutls_record_send(backend->session, mem, len); + struct ssl_backend_data *backend = connssl->backend; + ssize_t rc = gnutls_record_send(backend->session, mem, len); if(rc < 0) { *curlcode = (rc == GNUTLS_E_AGAIN) @@ -1422,20 +1422,20 @@ static ssize_t gtls_send(struct connectdata *conn, static void close_one(struct ssl_connect_data *connssl) { - struct ssl_backend_data *backend = connssl->backend; - if(backend->session) { - gnutls_bye(backend->session, GNUTLS_SHUT_WR); - gnutls_deinit(backend->session); - backend->session = NULL; + struct ssl_backend_data *backend = connssl->backend; + if(backend->session) { + gnutls_bye(backend->session, GNUTLS_SHUT_WR); + gnutls_deinit(backend->session); + backend->session = NULL; } - if(backend->cred) { - gnutls_certificate_free_credentials(backend->cred); - backend->cred = NULL; + if(backend->cred) { + gnutls_certificate_free_credentials(backend->cred); + backend->cred = NULL; } -#ifdef HAVE_GNUTLS_SRP - if(backend->srp_client_cred) { - gnutls_srp_free_client_credentials(backend->srp_client_cred); - backend->srp_client_cred = NULL; +#ifdef HAVE_GNUTLS_SRP + if(backend->srp_client_cred) { + gnutls_srp_free_client_credentials(backend->srp_client_cred); + backend->srp_client_cred = NULL; } #endif } @@ -1443,9 +1443,9 @@ static void close_one(struct ssl_connect_data *connssl) static void Curl_gtls_close(struct connectdata *conn, int sockindex) { close_one(&conn->ssl[sockindex]); -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY close_one(&conn->proxy_ssl[sockindex]); -#endif +#endif } /* @@ -1455,7 +1455,7 @@ static void Curl_gtls_close(struct connectdata *conn, int sockindex) static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; int retval = 0; struct Curl_easy *data = conn->data; @@ -1466,10 +1466,10 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) we do not send one. Let's hope other servers do the same... */ if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) - gnutls_bye(backend->session, GNUTLS_SHUT_WR); + gnutls_bye(backend->session, GNUTLS_SHUT_WR); #endif - if(backend->session) { + if(backend->session) { ssize_t result; bool done = FALSE; char buf[120]; @@ -1480,7 +1480,7 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) if(what > 0) { /* Something to read, let's do it and hope that it is the close notify alert from the server */ - result = gnutls_record_recv(backend->session, + result = gnutls_record_recv(backend->session, buf, sizeof(buf)); switch(result) { case 0: @@ -1510,18 +1510,18 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) done = TRUE; } } - gnutls_deinit(backend->session); + gnutls_deinit(backend->session); } - gnutls_certificate_free_credentials(backend->cred); + gnutls_certificate_free_credentials(backend->cred); -#ifdef HAVE_GNUTLS_SRP +#ifdef HAVE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP && SSL_SET_OPTION(username) != NULL) - gnutls_srp_free_client_credentials(backend->srp_client_cred); + gnutls_srp_free_client_credentials(backend->srp_client_cred); #endif - backend->cred = NULL; - backend->session = NULL; + backend->cred = NULL; + backend->session = NULL; return retval; } @@ -1533,10 +1533,10 @@ static ssize_t gtls_recv(struct connectdata *conn, /* connection data */ CURLcode *curlcode) { struct ssl_connect_data *connssl = &conn->ssl[num]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; ssize_t ret; - ret = gnutls_record_recv(backend->session, buf, buffersize); + ret = gnutls_record_recv(backend->session, buf, buffersize); if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) { *curlcode = CURLE_AGAIN; return -1; @@ -1658,9 +1658,9 @@ static bool Curl_gtls_cert_status_request(void) static void *Curl_gtls_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) { - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; (void)info; - return backend->session; + return backend->session; } const struct Curl_ssl Curl_ssl_gnutls = { diff --git a/contrib/libs/curl/lib/vtls/gtls.h b/contrib/libs/curl/lib/vtls/gtls.h index 1a146a3a93..6eb03d45b3 100644 --- a/contrib/libs/curl/lib/vtls/gtls.h +++ b/contrib/libs/curl/lib/vtls/gtls.h @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is diff --git a/contrib/libs/curl/lib/vtls/keylog.c b/contrib/libs/curl/lib/vtls/keylog.c index a45945f8f5..d23ca68998 100644 --- a/contrib/libs/curl/lib/vtls/keylog.c +++ b/contrib/libs/curl/lib/vtls/keylog.c @@ -1,156 +1,156 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "keylog.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -#define KEYLOG_LABEL_MAXLEN (sizeof("CLIENT_HANDSHAKE_TRAFFIC_SECRET") - 1) - -#define CLIENT_RANDOM_SIZE 32 - -/* - * The master secret in TLS 1.2 and before is always 48 bytes. In TLS 1.3, the - * secret size depends on the cipher suite's hash function which is 32 bytes - * for SHA-256 and 48 bytes for SHA-384. - */ -#define SECRET_MAXLEN 48 - - -/* The fp for the open SSLKEYLOGFILE, or NULL if not open */ -static FILE *keylog_file_fp; - -void -Curl_tls_keylog_open(void) -{ - char *keylog_file_name; - - if(!keylog_file_fp) { - keylog_file_name = curl_getenv("SSLKEYLOGFILE"); - if(keylog_file_name) { - keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT); - if(keylog_file_fp) { -#ifdef WIN32 - if(setvbuf(keylog_file_fp, NULL, _IONBF, 0)) -#else - if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) -#endif - { - fclose(keylog_file_fp); - keylog_file_fp = NULL; - } - } - Curl_safefree(keylog_file_name); - } - } -} - -void -Curl_tls_keylog_close(void) -{ - if(keylog_file_fp) { - fclose(keylog_file_fp); - keylog_file_fp = NULL; - } -} - -bool -Curl_tls_keylog_enabled(void) -{ - return keylog_file_fp != NULL; -} - -bool -Curl_tls_keylog_write_line(const char *line) -{ - /* The current maximum valid keylog line length LF and NUL is 195. */ - size_t linelen; - char buf[256]; - - if(!keylog_file_fp || !line) { - return false; - } - - linelen = strlen(line); - if(linelen == 0 || linelen > sizeof(buf) - 2) { - /* Empty line or too big to fit in a LF and NUL. */ - return false; - } - - memcpy(buf, line, linelen); - if(line[linelen - 1] != '\n') { - buf[linelen++] = '\n'; - } - buf[linelen] = '\0'; - - /* Using fputs here instead of fprintf since libcurl's fprintf replacement - may not be thread-safe. */ - fputs(buf, keylog_file_fp); - return true; -} - -bool -Curl_tls_keylog_write(const char *label, - const unsigned char client_random[CLIENT_RANDOM_SIZE], - const unsigned char *secret, size_t secretlen) -{ - const char *hex = "0123456789ABCDEF"; - size_t pos, i; - char line[KEYLOG_LABEL_MAXLEN + 1 + 2 * CLIENT_RANDOM_SIZE + 1 + - 2 * SECRET_MAXLEN + 1 + 1]; - - if(!keylog_file_fp) { - return false; - } - - pos = strlen(label); - if(pos > KEYLOG_LABEL_MAXLEN || !secretlen || secretlen > SECRET_MAXLEN) { - /* Should never happen - sanity check anyway. */ - return false; - } - - memcpy(line, label, pos); - line[pos++] = ' '; - - /* Client Random */ - for(i = 0; i < CLIENT_RANDOM_SIZE; i++) { - line[pos++] = hex[client_random[i] >> 4]; - line[pos++] = hex[client_random[i] & 0xF]; - } - line[pos++] = ' '; - - /* Secret */ - for(i = 0; i < secretlen; i++) { - line[pos++] = hex[secret[i] >> 4]; - line[pos++] = hex[secret[i] & 0xF]; - } - line[pos++] = '\n'; - line[pos] = '\0'; - - /* Using fputs here instead of fprintf since libcurl's fprintf replacement - may not be thread-safe. */ - fputs(line, keylog_file_fp); - return true; -} +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2020, 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 + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#include "keylog.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#define KEYLOG_LABEL_MAXLEN (sizeof("CLIENT_HANDSHAKE_TRAFFIC_SECRET") - 1) + +#define CLIENT_RANDOM_SIZE 32 + +/* + * The master secret in TLS 1.2 and before is always 48 bytes. In TLS 1.3, the + * secret size depends on the cipher suite's hash function which is 32 bytes + * for SHA-256 and 48 bytes for SHA-384. + */ +#define SECRET_MAXLEN 48 + + +/* The fp for the open SSLKEYLOGFILE, or NULL if not open */ +static FILE *keylog_file_fp; + +void +Curl_tls_keylog_open(void) +{ + char *keylog_file_name; + + if(!keylog_file_fp) { + keylog_file_name = curl_getenv("SSLKEYLOGFILE"); + if(keylog_file_name) { + keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT); + if(keylog_file_fp) { +#ifdef WIN32 + if(setvbuf(keylog_file_fp, NULL, _IONBF, 0)) +#else + if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) +#endif + { + fclose(keylog_file_fp); + keylog_file_fp = NULL; + } + } + Curl_safefree(keylog_file_name); + } + } +} + +void +Curl_tls_keylog_close(void) +{ + if(keylog_file_fp) { + fclose(keylog_file_fp); + keylog_file_fp = NULL; + } +} + +bool +Curl_tls_keylog_enabled(void) +{ + return keylog_file_fp != NULL; +} + +bool +Curl_tls_keylog_write_line(const char *line) +{ + /* The current maximum valid keylog line length LF and NUL is 195. */ + size_t linelen; + char buf[256]; + + if(!keylog_file_fp || !line) { + return false; + } + + linelen = strlen(line); + if(linelen == 0 || linelen > sizeof(buf) - 2) { + /* Empty line or too big to fit in a LF and NUL. */ + return false; + } + + memcpy(buf, line, linelen); + if(line[linelen - 1] != '\n') { + buf[linelen++] = '\n'; + } + buf[linelen] = '\0'; + + /* Using fputs here instead of fprintf since libcurl's fprintf replacement + may not be thread-safe. */ + fputs(buf, keylog_file_fp); + return true; +} + +bool +Curl_tls_keylog_write(const char *label, + const unsigned char client_random[CLIENT_RANDOM_SIZE], + const unsigned char *secret, size_t secretlen) +{ + const char *hex = "0123456789ABCDEF"; + size_t pos, i; + char line[KEYLOG_LABEL_MAXLEN + 1 + 2 * CLIENT_RANDOM_SIZE + 1 + + 2 * SECRET_MAXLEN + 1 + 1]; + + if(!keylog_file_fp) { + return false; + } + + pos = strlen(label); + if(pos > KEYLOG_LABEL_MAXLEN || !secretlen || secretlen > SECRET_MAXLEN) { + /* Should never happen - sanity check anyway. */ + return false; + } + + memcpy(line, label, pos); + line[pos++] = ' '; + + /* Client Random */ + for(i = 0; i < CLIENT_RANDOM_SIZE; i++) { + line[pos++] = hex[client_random[i] >> 4]; + line[pos++] = hex[client_random[i] & 0xF]; + } + line[pos++] = ' '; + + /* Secret */ + for(i = 0; i < secretlen; i++) { + line[pos++] = hex[secret[i] >> 4]; + line[pos++] = hex[secret[i] & 0xF]; + } + line[pos++] = '\n'; + line[pos] = '\0'; + + /* Using fputs here instead of fprintf since libcurl's fprintf replacement + may not be thread-safe. */ + fputs(line, keylog_file_fp); + return true; +} diff --git a/contrib/libs/curl/lib/vtls/keylog.h b/contrib/libs/curl/lib/vtls/keylog.h index 63626da90a..858ddbb9f1 100644 --- a/contrib/libs/curl/lib/vtls/keylog.h +++ b/contrib/libs/curl/lib/vtls/keylog.h @@ -1,56 +1,56 @@ -#ifndef HEADER_CURL_KEYLOG_H -#define HEADER_CURL_KEYLOG_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -/* - * Opens the TLS key log file if requested by the user. The SSLKEYLOGFILE - * environment variable specifies the output file. - */ -void Curl_tls_keylog_open(void); - -/* - * Closes the TLS key log file if not already. - */ -void Curl_tls_keylog_close(void); - -/* - * Returns true if the user successfully enabled the TLS key log file. - */ -bool Curl_tls_keylog_enabled(void); - -/* - * Appends a key log file entry. - * Returns true iff the key log file is open and a valid entry was provided. - */ -bool Curl_tls_keylog_write(const char *label, - const unsigned char client_random[32], - const unsigned char *secret, size_t secretlen); - -/* - * Appends a line to the key log file, ensure it is terminated by a LF. - * Returns true iff the key log file is open and a valid line was provided. - */ -bool Curl_tls_keylog_write_line(const char *line); - -#endif /* HEADER_CURL_KEYLOG_H */ +#ifndef HEADER_CURL_KEYLOG_H +#define HEADER_CURL_KEYLOG_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2020, 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 + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +/* + * Opens the TLS key log file if requested by the user. The SSLKEYLOGFILE + * environment variable specifies the output file. + */ +void Curl_tls_keylog_open(void); + +/* + * Closes the TLS key log file if not already. + */ +void Curl_tls_keylog_close(void); + +/* + * Returns true if the user successfully enabled the TLS key log file. + */ +bool Curl_tls_keylog_enabled(void); + +/* + * Appends a key log file entry. + * Returns true iff the key log file is open and a valid entry was provided. + */ +bool Curl_tls_keylog_write(const char *label, + const unsigned char client_random[32], + const unsigned char *secret, size_t secretlen); + +/* + * Appends a line to the key log file, ensure it is terminated by a LF. + * Returns true iff the key log file is open and a valid line was provided. + */ +bool Curl_tls_keylog_write_line(const char *line); + +#endif /* HEADER_CURL_KEYLOG_H */ diff --git a/contrib/libs/curl/lib/vtls/mbedtls.c b/contrib/libs/curl/lib/vtls/mbedtls.c index e30f660fbb..ef85bc0944 100644 --- a/contrib/libs/curl/lib/vtls/mbedtls.c +++ b/contrib/libs/curl/lib/vtls/mbedtls.c @@ -6,11 +6,11 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com> - * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -31,9 +31,9 @@ #ifdef USE_MBEDTLS -/* Define this to enable lots of debugging for mbedTLS */ -/* #define MBEDTLS_DEBUG */ - +/* Define this to enable lots of debugging for mbedTLS */ +/* #define MBEDTLS_DEBUG */ + #error #include <mbedtls/version.h> #if MBEDTLS_VERSION_NUMBER >= 0x02040000 #error #include <mbedtls/net_sockets.h> @@ -49,12 +49,12 @@ #error #include <mbedtls/ctr_drbg.h> #error #include <mbedtls/sha256.h> -#if MBEDTLS_VERSION_MAJOR >= 2 -# ifdef MBEDTLS_DEBUG -# error #include <mbedtls/debug.h> -# endif -#endif - +#if MBEDTLS_VERSION_MAJOR >= 2 +# ifdef MBEDTLS_DEBUG +# error #include <mbedtls/debug.h> +# endif +#endif + #include "urldata.h" #include "sendf.h" #include "inet_pton.h" @@ -64,7 +64,7 @@ #include "connect.h" /* for the connect timeout */ #include "select.h" #include "multiif.h" -#error #include "mbedtls_threadlock.h" +#error #include "mbedtls_threadlock.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -98,12 +98,12 @@ static int entropy_init_initialized = 0; static void entropy_init_mutex(mbedtls_entropy_context *ctx) { /* lock 0 = entropy_init_mutex() */ - Curl_mbedtlsthreadlock_lock_function(0); + Curl_mbedtlsthreadlock_lock_function(0); if(entropy_init_initialized == 0) { mbedtls_entropy_init(ctx); entropy_init_initialized = 1; } - Curl_mbedtlsthreadlock_unlock_function(0); + Curl_mbedtlsthreadlock_unlock_function(0); } /* end of entropy_init_mutex() */ @@ -112,9 +112,9 @@ static int entropy_func_mutex(void *data, unsigned char *output, size_t len) { int ret; /* lock 1 = entropy_func_mutex() */ - Curl_mbedtlsthreadlock_lock_function(1); + Curl_mbedtlsthreadlock_lock_function(1); ret = mbedtls_entropy_func(data, output, len); - Curl_mbedtlsthreadlock_unlock_function(1); + Curl_mbedtlsthreadlock_unlock_function(1); return ret; } @@ -200,7 +200,7 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex) { struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1; int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1; long ssl_version = SSL_CONN_CONFIG(version); @@ -232,9 +232,9 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex) return result; } - mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, + mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, mbedtls_ver_min); - mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, + mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, mbedtls_ver_max); return result; @@ -245,21 +245,21 @@ mbed_connect_step1(struct connectdata *conn, int sockindex) { struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + 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 bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const ssl_capath = SSL_CONN_CONFIG(CApath); - char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); + char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const char * const hostname = conn->host.name; - const long int port = conn->remote_port; -#endif +#else + const char * const hostname = conn->host.name; + const long int port = conn->remote_port; +#endif int ret = -1; char errorbuf[128]; errorbuf[0] = 0; @@ -272,9 +272,9 @@ mbed_connect_step1(struct connectdata *conn, #ifdef THREADING_SUPPORT entropy_init_mutex(&ts_entropy); - mbedtls_ctr_drbg_init(&backend->ctr_drbg); + mbedtls_ctr_drbg_init(&backend->ctr_drbg); - ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex, + ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex, &ts_entropy, NULL, 0); if(ret) { #ifdef MBEDTLS_ERROR_C @@ -284,11 +284,11 @@ mbed_connect_step1(struct connectdata *conn, -ret, errorbuf); } #else - mbedtls_entropy_init(&backend->entropy); - mbedtls_ctr_drbg_init(&backend->ctr_drbg); + mbedtls_entropy_init(&backend->entropy); + mbedtls_ctr_drbg_init(&backend->ctr_drbg); - ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func, - &backend->entropy, NULL, 0); + ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func, + &backend->entropy, NULL, 0); if(ret) { #ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); @@ -299,10 +299,10 @@ mbed_connect_step1(struct connectdata *conn, #endif /* THREADING_SUPPORT */ /* Load the trusted CA */ - mbedtls_x509_crt_init(&backend->cacert); + mbedtls_x509_crt_init(&backend->cacert); if(ssl_cafile) { - ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile); + ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile); if(ret<0) { #ifdef MBEDTLS_ERROR_C @@ -317,7 +317,7 @@ mbed_connect_step1(struct connectdata *conn, } if(ssl_capath) { - ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath); + ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath); if(ret<0) { #ifdef MBEDTLS_ERROR_C @@ -332,10 +332,10 @@ mbed_connect_step1(struct connectdata *conn, } /* Load the client certificate */ - mbedtls_x509_crt_init(&backend->clicert); + mbedtls_x509_crt_init(&backend->clicert); if(ssl_cert) { - ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert); + ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert); if(ret) { #ifdef MBEDTLS_ERROR_C @@ -349,13 +349,13 @@ mbed_connect_step1(struct connectdata *conn, } /* Load the client private key */ - mbedtls_pk_init(&backend->pk); + mbedtls_pk_init(&backend->pk); if(SSL_SET_OPTION(key)) { - ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key), + ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key), SSL_SET_OPTION(key_passwd)); - if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || - mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) + if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || + mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; if(ret) { @@ -370,10 +370,10 @@ mbed_connect_step1(struct connectdata *conn, } /* Load the CRL */ - mbedtls_x509_crl_init(&backend->crl); + mbedtls_x509_crl_init(&backend->crl); if(ssl_crlfile) { - ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile); + ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile); if(ret) { #ifdef MBEDTLS_ERROR_C @@ -388,14 +388,14 @@ mbed_connect_step1(struct connectdata *conn, infof(data, "mbedTLS: Connecting to %s:%ld\n", hostname, port); - mbedtls_ssl_config_init(&backend->config); + mbedtls_ssl_config_init(&backend->config); - mbedtls_ssl_init(&backend->ssl); - if(mbedtls_ssl_setup(&backend->ssl, &backend->config)) { + mbedtls_ssl_init(&backend->ssl); + if(mbedtls_ssl_setup(&backend->ssl, &backend->config)) { failf(data, "mbedTLS: ssl_init failed"); return CURLE_SSL_CONNECT_ERROR; } - ret = mbedtls_ssl_config_defaults(&backend->config, + ret = mbedtls_ssl_config_defaults(&backend->config, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); @@ -405,20 +405,20 @@ mbed_connect_step1(struct connectdata *conn, } /* new profile with RSA min key len = 1024 ... */ - mbedtls_ssl_conf_cert_profile(&backend->config, + mbedtls_ssl_conf_cert_profile(&backend->config, &mbedtls_x509_crt_profile_fr); switch(SSL_CONN_CONFIG(version)) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, + mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n"); break; case CURL_SSLVERSION_SSLv3: - mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, + mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); - mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, + mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); infof(data, "mbedTLS: Set SSL version to SSLv3\n"); break; @@ -437,25 +437,25 @@ mbed_connect_step1(struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } - mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_OPTIONAL); + mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_OPTIONAL); - mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random, - &backend->ctr_drbg); - mbedtls_ssl_set_bio(&backend->ssl, &conn->sock[sockindex], + mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random, + &backend->ctr_drbg); + mbedtls_ssl_set_bio(&backend->ssl, &conn->sock[sockindex], mbedtls_net_send, mbedtls_net_recv, NULL /* rev_timeout() */); - mbedtls_ssl_conf_ciphersuites(&backend->config, + mbedtls_ssl_conf_ciphersuites(&backend->config, mbedtls_ssl_list_ciphersuites()); #if defined(MBEDTLS_SSL_RENEGOTIATION) - mbedtls_ssl_conf_renegotiation(&backend->config, + mbedtls_ssl_conf_renegotiation(&backend->config, MBEDTLS_SSL_RENEGOTIATION_ENABLED); #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) - mbedtls_ssl_conf_session_tickets(&backend->config, + mbedtls_ssl_conf_session_tickets(&backend->config, MBEDTLS_SSL_SESSION_TICKETS_DISABLED); #endif @@ -465,7 +465,7 @@ mbed_connect_step1(struct connectdata *conn, Curl_ssl_sessionid_lock(conn); if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) { - ret = mbedtls_ssl_set_session(&backend->ssl, old_session); + ret = mbedtls_ssl_set_session(&backend->ssl, old_session); if(ret) { Curl_ssl_sessionid_unlock(conn); failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret); @@ -476,15 +476,15 @@ mbed_connect_step1(struct connectdata *conn, Curl_ssl_sessionid_unlock(conn); } - mbedtls_ssl_conf_ca_chain(&backend->config, - &backend->cacert, - &backend->crl); + mbedtls_ssl_conf_ca_chain(&backend->config, + &backend->cacert, + &backend->crl); if(SSL_SET_OPTION(key)) { - mbedtls_ssl_conf_own_cert(&backend->config, - &backend->clicert, &backend->pk); + mbedtls_ssl_conf_own_cert(&backend->config, + &backend->clicert, &backend->pk); } - if(mbedtls_ssl_set_hostname(&backend->ssl, hostname)) { + if(mbedtls_ssl_set_hostname(&backend->ssl, hostname)) { /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name to set in the SNI extension. So even if curl connects to a host specified as an IP address, this function must be used. */ @@ -494,7 +494,7 @@ mbed_connect_step1(struct connectdata *conn, #ifdef HAS_ALPN if(conn->bits.tls_enable_alpn) { - const char **p = &backend->protocols[0]; + const char **p = &backend->protocols[0]; #ifdef USE_NGHTTP2 if(data->set.httpversion >= CURL_HTTP_VERSION_2) *p++ = NGHTTP2_PROTO_VERSION_ID; @@ -503,19 +503,19 @@ mbed_connect_step1(struct connectdata *conn, *p = NULL; /* this function doesn't clone the protocols array, which is why we need to keep it around */ - if(mbedtls_ssl_conf_alpn_protocols(&backend->config, - &backend->protocols[0])) { + if(mbedtls_ssl_conf_alpn_protocols(&backend->config, + &backend->protocols[0])) { failf(data, "Failed setting ALPN protocols"); return CURLE_SSL_CONNECT_ERROR; } - for(p = &backend->protocols[0]; *p; ++p) + for(p = &backend->protocols[0]; *p; ++p) infof(data, "ALPN, offering %s\n", *p); } #endif #ifdef MBEDTLS_DEBUG /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */ - mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data); + mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data); /* - 0 No debug * - 1 Error * - 2 State change @@ -527,7 +527,7 @@ mbed_connect_step1(struct connectdata *conn, /* give application a chance to interfere with mbedTLS set up. */ if(data->set.ssl.fsslctx) { - ret = (*data->set.ssl.fsslctx)(data, &backend->config, + ret = (*data->set.ssl.fsslctx)(data, &backend->config, data->set.ssl.fsslctxp); if(ret) { failf(data, "error signaled by ssl ctx callback"); @@ -546,22 +546,22 @@ mbed_connect_step2(struct connectdata *conn, { int ret; struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; const mbedtls_x509_crt *peercert; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY const char * const pinnedpubkey = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; -#else - const char * const pinnedpubkey = - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; -#endif + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; +#else + const char * const pinnedpubkey = + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; +#endif conn->recv[sockindex] = mbed_recv; conn->send[sockindex] = mbed_send; - ret = mbedtls_ssl_handshake(&backend->ssl); + ret = mbedtls_ssl_handshake(&backend->ssl); if(ret == MBEDTLS_ERR_SSL_WANT_READ) { connssl->connecting_state = ssl_connect_2_reading; @@ -583,10 +583,10 @@ mbed_connect_step2(struct connectdata *conn, } infof(data, "mbedTLS: Handshake complete, cipher is %s\n", - mbedtls_ssl_get_ciphersuite(&backend->ssl) + mbedtls_ssl_get_ciphersuite(&backend->ssl) ); - ret = mbedtls_ssl_get_verify_result(&backend->ssl); + ret = mbedtls_ssl_get_verify_result(&backend->ssl); if(!SSL_CONN_CONFIG(verifyhost)) /* Ignore hostname errors if verifyhost is disabled */ @@ -605,13 +605,13 @@ mbed_connect_step2(struct connectdata *conn, else if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED) failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); - else if(ret & MBEDTLS_X509_BADCERT_FUTURE) - failf(data, "Cert verify failed: BADCERT_FUTURE"); - + else if(ret & MBEDTLS_X509_BADCERT_FUTURE) + failf(data, "Cert verify failed: BADCERT_FUTURE"); + return CURLE_PEER_FAILED_VERIFICATION; } - peercert = mbedtls_ssl_get_peer_cert(&backend->ssl); + peercert = mbedtls_ssl_get_peer_cert(&backend->ssl); if(peercert && data->set.verbose) { const size_t bufsize = 16384; @@ -681,7 +681,7 @@ mbed_connect_step2(struct connectdata *conn, #ifdef HAS_ALPN if(conn->bits.tls_enable_alpn) { - const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&backend->ssl); + const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&backend->ssl); if(next_protocol) { infof(data, "ALPN, server accepted to use %s\n", next_protocol); @@ -718,7 +718,7 @@ mbed_connect_step3(struct connectdata *conn, { CURLcode retcode = CURLE_OK; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; struct Curl_easy *data = conn->data; DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); @@ -734,7 +734,7 @@ mbed_connect_step3(struct connectdata *conn, mbedtls_ssl_session_init(our_ssl_sessionid); - ret = mbedtls_ssl_get_session(&backend->ssl, our_ssl_sessionid); + ret = mbedtls_ssl_get_session(&backend->ssl, our_ssl_sessionid); if(ret) { if(ret != MBEDTLS_ERR_SSL_ALLOC_FAILED) mbedtls_ssl_session_free(our_ssl_sessionid); @@ -768,10 +768,10 @@ static ssize_t mbed_send(struct connectdata *conn, int sockindex, CURLcode *curlcode) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; int ret = -1; - ret = mbedtls_ssl_write(&backend->ssl, + ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len); if(ret < 0) { @@ -791,16 +791,16 @@ static void Curl_mbedtls_close_all(struct Curl_easy *data) static void Curl_mbedtls_close(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - mbedtls_pk_free(&backend->pk); - mbedtls_x509_crt_free(&backend->clicert); - mbedtls_x509_crt_free(&backend->cacert); - mbedtls_x509_crl_free(&backend->crl); - mbedtls_ssl_config_free(&backend->config); - mbedtls_ssl_free(&backend->ssl); - mbedtls_ctr_drbg_free(&backend->ctr_drbg); + struct ssl_backend_data *backend = connssl->backend; + mbedtls_pk_free(&backend->pk); + mbedtls_x509_crt_free(&backend->clicert); + mbedtls_x509_crt_free(&backend->cacert); + mbedtls_x509_crl_free(&backend->crl); + mbedtls_ssl_config_free(&backend->config); + mbedtls_ssl_free(&backend->ssl); + mbedtls_ctr_drbg_free(&backend->ctr_drbg); #ifndef THREADING_SUPPORT - mbedtls_entropy_free(&backend->entropy); + mbedtls_entropy_free(&backend->entropy); #endif /* THREADING_SUPPORT */ } @@ -809,12 +809,12 @@ static ssize_t mbed_recv(struct connectdata *conn, int num, CURLcode *curlcode) { struct ssl_connect_data *connssl = &conn->ssl[num]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; int ret = -1; ssize_t len = -1; memset(buf, 0, buffersize); - ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, + ret = mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, buffersize); if(ret <= 0) { @@ -908,7 +908,7 @@ mbed_connect_common(struct connectdata *conn, struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; curl_socket_t sockfd = conn->sock[sockindex]; - timediff_t timeout_ms; + timediff_t timeout_ms; int what; /* check if the connection has already been established */ @@ -1038,20 +1038,20 @@ static CURLcode Curl_mbedtls_connect(struct connectdata *conn, int sockindex) */ static int Curl_mbedtls_init(void) { - return Curl_mbedtlsthreadlock_thread_setup(); + return Curl_mbedtlsthreadlock_thread_setup(); } static void Curl_mbedtls_cleanup(void) { - (void)Curl_mbedtlsthreadlock_thread_cleanup(); + (void)Curl_mbedtlsthreadlock_thread_cleanup(); } static bool Curl_mbedtls_data_pending(const struct connectdata *conn, int sockindex) { const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; - return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0; + struct ssl_backend_data *backend = connssl->backend; + return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0; } static CURLcode Curl_mbedtls_sha256sum(const unsigned char *input, @@ -1073,9 +1073,9 @@ static CURLcode Curl_mbedtls_sha256sum(const unsigned char *input, static void *Curl_mbedtls_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) { - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; (void)info; - return &backend->ssl; + return &backend->ssl; } const struct Curl_ssl Curl_ssl_mbedtls = { diff --git a/contrib/libs/curl/lib/vtls/mbedtls.h b/contrib/libs/curl/lib/vtls/mbedtls.h index 1abd331ea9..b263d67318 100644 --- a/contrib/libs/curl/lib/vtls/mbedtls.h +++ b/contrib/libs/curl/lib/vtls/mbedtls.h @@ -7,12 +7,12 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com> * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is diff --git a/contrib/libs/curl/lib/vtls/mbedtls_threadlock.c b/contrib/libs/curl/lib/vtls/mbedtls_threadlock.c index d3c4698131..3216118500 100644 --- a/contrib/libs/curl/lib/vtls/mbedtls_threadlock.c +++ b/contrib/libs/curl/lib/vtls/mbedtls_threadlock.c @@ -1,144 +1,144 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2013 - 2020, 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 - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_MBEDTLS) && \ - ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \ - (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H))) - -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) -# include <pthread.h> -# define MBEDTLS_MUTEX_T pthread_mutex_t -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) -# include <process.h> -# define MBEDTLS_MUTEX_T HANDLE -#endif - -#error #include "mbedtls_threadlock.h" -#include "curl_printf.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* number of thread locks */ -#define NUMT 2 - -/* This array will store all of the mutexes available to Mbedtls. */ -static MBEDTLS_MUTEX_T *mutex_buf = NULL; - -int Curl_mbedtlsthreadlock_thread_setup(void) -{ - int i; - - mutex_buf = calloc(NUMT * sizeof(MBEDTLS_MUTEX_T), 1); - if(!mutex_buf) - return 0; /* error, no number of threads defined */ - - for(i = 0; i < NUMT; i++) { - int ret; -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) - ret = pthread_mutex_init(&mutex_buf[i], NULL); - if(ret) - return 0; /* pthread_mutex_init failed */ -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) - mutex_buf[i] = CreateMutex(0, FALSE, 0); - if(mutex_buf[i] == 0) - return 0; /* CreateMutex failed */ -#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ - } - - return 1; /* OK */ -} - -int Curl_mbedtlsthreadlock_thread_cleanup(void) -{ - int i; - - if(!mutex_buf) - return 0; /* error, no threads locks defined */ - - for(i = 0; i < NUMT; i++) { - int ret; -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) - ret = pthread_mutex_destroy(&mutex_buf[i]); - if(ret) - return 0; /* pthread_mutex_destroy failed */ -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) - ret = CloseHandle(mutex_buf[i]); - if(!ret) - return 0; /* CloseHandle failed */ -#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ - } - free(mutex_buf); - mutex_buf = NULL; - - return 1; /* OK */ -} - -int Curl_mbedtlsthreadlock_lock_function(int n) -{ - if(n < NUMT) { - int ret; -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) - ret = pthread_mutex_lock(&mutex_buf[n]); - if(ret) { - DEBUGF(fprintf(stderr, - "Error: mbedtlsthreadlock_lock_function failed\n")); - return 0; /* pthread_mutex_lock failed */ - } -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) - ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0); - if(ret) { - DEBUGF(fprintf(stderr, - "Error: mbedtlsthreadlock_lock_function failed\n")); - return 0; /* pthread_mutex_lock failed */ - } -#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ - } - return 1; /* OK */ -} - -int Curl_mbedtlsthreadlock_unlock_function(int n) -{ - if(n < NUMT) { - int ret; -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) - ret = pthread_mutex_unlock(&mutex_buf[n]); - if(ret) { - DEBUGF(fprintf(stderr, - "Error: mbedtlsthreadlock_unlock_function failed\n")); - return 0; /* pthread_mutex_unlock failed */ - } -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) - ret = ReleaseMutex(mutex_buf[n]); - if(!ret) { - DEBUGF(fprintf(stderr, - "Error: mbedtlsthreadlock_unlock_function failed\n")); - return 0; /* pthread_mutex_lock failed */ - } -#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ - } - return 1; /* OK */ -} - -#endif /* USE_MBEDTLS */ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2013 - 2020, 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 + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "curl_setup.h" + +#if defined(USE_MBEDTLS) && \ + ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \ + (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H))) + +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) +# include <pthread.h> +# define MBEDTLS_MUTEX_T pthread_mutex_t +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) +# include <process.h> +# define MBEDTLS_MUTEX_T HANDLE +#endif + +#error #include "mbedtls_threadlock.h" +#include "curl_printf.h" +#include "curl_memory.h" +/* The last #include file should be: */ +#include "memdebug.h" + +/* number of thread locks */ +#define NUMT 2 + +/* This array will store all of the mutexes available to Mbedtls. */ +static MBEDTLS_MUTEX_T *mutex_buf = NULL; + +int Curl_mbedtlsthreadlock_thread_setup(void) +{ + int i; + + mutex_buf = calloc(NUMT * sizeof(MBEDTLS_MUTEX_T), 1); + if(!mutex_buf) + return 0; /* error, no number of threads defined */ + + for(i = 0; i < NUMT; i++) { + int ret; +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) + ret = pthread_mutex_init(&mutex_buf[i], NULL); + if(ret) + return 0; /* pthread_mutex_init failed */ +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) + mutex_buf[i] = CreateMutex(0, FALSE, 0); + if(mutex_buf[i] == 0) + return 0; /* CreateMutex failed */ +#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ + } + + return 1; /* OK */ +} + +int Curl_mbedtlsthreadlock_thread_cleanup(void) +{ + int i; + + if(!mutex_buf) + return 0; /* error, no threads locks defined */ + + for(i = 0; i < NUMT; i++) { + int ret; +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) + ret = pthread_mutex_destroy(&mutex_buf[i]); + if(ret) + return 0; /* pthread_mutex_destroy failed */ +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) + ret = CloseHandle(mutex_buf[i]); + if(!ret) + return 0; /* CloseHandle failed */ +#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ + } + free(mutex_buf); + mutex_buf = NULL; + + return 1; /* OK */ +} + +int Curl_mbedtlsthreadlock_lock_function(int n) +{ + if(n < NUMT) { + int ret; +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) + ret = pthread_mutex_lock(&mutex_buf[n]); + if(ret) { + DEBUGF(fprintf(stderr, + "Error: mbedtlsthreadlock_lock_function failed\n")); + return 0; /* pthread_mutex_lock failed */ + } +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) + ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0); + if(ret) { + DEBUGF(fprintf(stderr, + "Error: mbedtlsthreadlock_lock_function failed\n")); + return 0; /* pthread_mutex_lock failed */ + } +#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ + } + return 1; /* OK */ +} + +int Curl_mbedtlsthreadlock_unlock_function(int n) +{ + if(n < NUMT) { + int ret; +#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) + ret = pthread_mutex_unlock(&mutex_buf[n]); + if(ret) { + DEBUGF(fprintf(stderr, + "Error: mbedtlsthreadlock_unlock_function failed\n")); + return 0; /* pthread_mutex_unlock failed */ + } +#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) + ret = ReleaseMutex(mutex_buf[n]); + if(!ret) { + DEBUGF(fprintf(stderr, + "Error: mbedtlsthreadlock_unlock_function failed\n")); + return 0; /* pthread_mutex_lock failed */ + } +#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ + } + return 1; /* OK */ +} + +#endif /* USE_MBEDTLS */ diff --git a/contrib/libs/curl/lib/vtls/mesalink.c b/contrib/libs/curl/lib/vtls/mesalink.c index 309786cf83..4b57a78b8f 100644 --- a/contrib/libs/curl/lib/vtls/mesalink.c +++ b/contrib/libs/curl/lib/vtls/mesalink.c @@ -6,11 +6,11 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com> - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -158,8 +158,8 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex) SSL_CONN_CONFIG(CApath))) { if(SSL_CONN_CONFIG(verifypeer)) { failf(data, - "error setting certificate verify locations: " - " CAfile: %s CApath: %s", + "error setting certificate verify locations: " + " CAfile: %s CApath: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none", SSL_CONN_CONFIG(CApath) ? @@ -173,18 +173,18 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex) else { infof(data, "successfully set certificate verify locations:\n"); } - infof(data, " CAfile: %s\n", - SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): "none"); - infof(data, " CApath: %s\n", - SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath): "none"); + infof(data, " CAfile: %s\n", + SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): "none"); + infof(data, " CApath: %s\n", + SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath): "none"); } - if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) { + 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, - SSL_SET_OPTION(primary.clientcert), - file_type) != 1) { + 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" " phrase?)"); return CURLE_SSL_CONNECT_ERROR; @@ -492,7 +492,7 @@ mesalink_connect_common(struct connectdata *conn, int sockindex, struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; curl_socket_t sockfd = conn->sock[sockindex]; - timediff_t timeout_ms; + timediff_t timeout_ms; int what; /* check if the connection has already been established */ @@ -540,8 +540,8 @@ mesalink_connect_common(struct connectdata *conn, int sockindex, ? sockfd : CURL_SOCKET_BAD; - what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, - nonblocking ? 0 : timeout_ms); + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking ? 0 : timeout_ms); if(what < 0) { /* fatal error */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); diff --git a/contrib/libs/curl/lib/vtls/mesalink.h b/contrib/libs/curl/lib/vtls/mesalink.h index 03f520c1dc..58cc3321cc 100644 --- a/contrib/libs/curl/lib/vtls/mesalink.h +++ b/contrib/libs/curl/lib/vtls/mesalink.h @@ -7,12 +7,12 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com> - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com> + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is diff --git a/contrib/libs/curl/lib/vtls/nss.c b/contrib/libs/curl/lib/vtls/nss.c index 59649ccc3a..c979d7cc72 100644 --- a/contrib/libs/curl/lib/vtls/nss.c +++ b/contrib/libs/curl/lib/vtls/nss.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -83,7 +83,7 @@ struct ssl_backend_data { PRFileDesc *handle; char *client_nickname; struct Curl_easy *data; - struct Curl_llist obj_list; + struct Curl_llist obj_list; PK11GenericObject *obj_clicert; }; @@ -91,32 +91,32 @@ static PRLock *nss_initlock = NULL; static PRLock *nss_crllock = NULL; static PRLock *nss_findslot_lock = NULL; static PRLock *nss_trustload_lock = NULL; -static struct Curl_llist nss_crl_list; +static struct Curl_llist nss_crl_list; static NSSInitContext *nss_context = NULL; static volatile int initialized = 0; /* type used to wrap pointers as list nodes */ struct ptr_list_wrap { void *ptr; - struct Curl_llist_element node; + struct Curl_llist_element node; }; -struct cipher_s { +struct cipher_s { const char *name; int num; -}; +}; #define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do { \ CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++); \ ptr->type = (_type); \ ptr->pValue = (_val); \ ptr->ulValueLen = (_len); \ -} while(0) +} while(0) #define CERT_NewTempCertificate __CERT_NewTempCertificate #define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0]) -static const struct cipher_s cipherlist[] = { +static const struct cipher_s cipherlist[] = { /* SSL2 cipher suites */ {"rc4", SSL_EN_RC4_128_WITH_MD5}, {"rc4-md5", SSL_EN_RC4_128_WITH_MD5}, @@ -430,7 +430,7 @@ static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name) } /* wrap 'ptr' as list node and tail-insert into 'list' */ -static CURLcode insert_wrapped_ptr(struct Curl_llist *list, void *ptr) +static CURLcode insert_wrapped_ptr(struct Curl_llist *list, void *ptr) { struct ptr_list_wrap *wrap = malloc(sizeof(*wrap)); if(!wrap) @@ -460,7 +460,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *connssl, const int slot_id = (cacert) ? 0 : 1; char *slot_name = aprintf("PEM Token #%d", slot_id); - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; if(!slot_name) return CURLE_OUT_OF_MEMORY; @@ -494,14 +494,14 @@ static CURLcode nss_create_object(struct ssl_connect_data *connssl, if(!obj) return result; - if(insert_wrapped_ptr(&backend->obj_list, obj) != CURLE_OK) { + if(insert_wrapped_ptr(&backend->obj_list, obj) != CURLE_OK) { PK11_DestroyGenericObject(obj); return CURLE_OUT_OF_MEMORY; } if(!cacert && CKO_CERTIFICATE == obj_class) /* store reference to a client certificate */ - backend->obj_clicert = obj; + backend->obj_clicert = obj; return CURLE_OK; } @@ -1027,7 +1027,7 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) CERTCertificate *cert; /* remember the cert verification result */ - SSL_SET_OPTION_LVALUE(certverifyresult) = err; + SSL_SET_OPTION_LVALUE(certverifyresult) = err; if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost)) /* we are asked not to verify the host name */ @@ -1080,8 +1080,8 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl, const char *pinnedpubkey) { CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - struct ssl_backend_data *backend = connssl->backend; - struct Curl_easy *data = backend->data; + struct ssl_backend_data *backend = connssl->backend; + struct Curl_easy *data = backend->data; CERTCertificate *cert; if(!pinnedpubkey) @@ -1089,7 +1089,7 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl, return CURLE_OK; /* get peer certificate */ - cert = SSL_PeerCertificate(backend->handle); + cert = SSL_PeerCertificate(backend->handle); if(cert) { /* extract public key from peer certificate */ SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert); @@ -1133,12 +1133,12 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock, struct SECKEYPrivateKeyStr **pRetKey) { struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg; - struct ssl_backend_data *backend = connssl->backend; - struct Curl_easy *data = backend->data; - const char *nickname = backend->client_nickname; + struct ssl_backend_data *backend = connssl->backend; + struct Curl_easy *data = backend->data; + const char *nickname = backend->client_nickname; static const char pem_slotname[] = "PEM Token #1"; - if(backend->obj_clicert) { + if(backend->obj_clicert) { /* use the cert/key provided by PEM reader */ SECItem cert_der = { 0, NULL, 0 }; void *proto_win = SSL_RevealPinArg(sock); @@ -1151,7 +1151,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock, return SECFailure; } - if(PK11_ReadRawAttribute(PK11_TypeGeneric, backend->obj_clicert, CKA_VALUE, + if(PK11_ReadRawAttribute(PK11_TypeGeneric, backend->obj_clicert, CKA_VALUE, &cert_der) != SECSuccess) { failf(data, "NSS: CKA_VALUE not found in PK11 generic object"); PK11_FreeSlot(slot); @@ -1501,12 +1501,12 @@ static void Curl_nss_cleanup(void) static int Curl_nss_check_cxn(struct connectdata *conn) { struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; int rc; char buf; rc = - PR_Recv(backend->handle, (void *)&buf, 1, PR_MSG_PEEK, + PR_Recv(backend->handle, (void *)&buf, 1, PR_MSG_PEEK, PR_SecondsToInterval(1)); if(rc > 0) return 1; /* connection still in place */ @@ -1520,27 +1520,27 @@ static int Curl_nss_check_cxn(struct connectdata *conn) static void nss_close(struct ssl_connect_data *connssl) { /* before the cleanup, check whether we are using a client certificate */ - struct ssl_backend_data *backend = connssl->backend; - const bool client_cert = (backend->client_nickname != NULL) - || (backend->obj_clicert != NULL); + struct ssl_backend_data *backend = connssl->backend; + const bool client_cert = (backend->client_nickname != NULL) + || (backend->obj_clicert != NULL); - free(backend->client_nickname); - backend->client_nickname = NULL; + free(backend->client_nickname); + backend->client_nickname = NULL; /* destroy all NSS objects in order to avoid failure of NSS shutdown */ - Curl_llist_destroy(&backend->obj_list, NULL); - backend->obj_clicert = NULL; + Curl_llist_destroy(&backend->obj_list, NULL); + backend->obj_clicert = NULL; - if(backend->handle) { + if(backend->handle) { if(client_cert) /* A server might require different authentication based on the * particular path being requested by the client. To support this * scenario, we must ensure that a connection will never reuse the * authentication data from a previous connection. */ - SSL_InvalidateSession(backend->handle); + SSL_InvalidateSession(backend->handle); - PR_Close(backend->handle); - backend->handle = NULL; + PR_Close(backend->handle); + backend->handle = NULL; } } @@ -1550,31 +1550,31 @@ static void nss_close(struct ssl_connect_data *connssl) static void Curl_nss_close(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex]; -#endif - struct ssl_backend_data *backend = connssl->backend; - - if(backend->handle -#ifndef CURL_DISABLE_PROXY - || connssl_proxy->backend->handle -#endif - ) { +#endif + struct ssl_backend_data *backend = connssl->backend; + + if(backend->handle +#ifndef CURL_DISABLE_PROXY + || connssl_proxy->backend->handle +#endif + ) { /* NSS closes the socket we previously handed to it, so we must mark it as closed to avoid double close */ fake_sclose(conn->sock[sockindex]); conn->sock[sockindex] = CURL_SOCKET_BAD; } -#ifndef CURL_DISABLE_PROXY - if(backend->handle) +#ifndef CURL_DISABLE_PROXY + if(backend->handle) /* nss_close(connssl) will transitively close also connssl_proxy->backend->handle if both are used. Clear it to avoid a double close leading to crash. */ connssl_proxy->backend->handle = NULL; - nss_close(connssl_proxy); -#endif + nss_close(connssl_proxy); +#endif nss_close(connssl); } @@ -1626,8 +1626,8 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn, if(capath && !capath[0]) capath = NULL; - infof(data, " CAfile: %s\n", cafile ? cafile : "none"); - infof(data, " CApath: %s\n", capath ? capath : "none"); + infof(data, " CAfile: %s\n", cafile ? cafile : "none"); + infof(data, " CApath: %s\n", capath ? capath : "none"); /* load libnssckbi.so if no other trust roots were specified */ use_trust_module = !cafile && !capath; @@ -1667,8 +1667,8 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn, if(!dir) return CURLE_SSL_CACERT_BADFILE; - while((entry = - PR_ReadDir(dir, (PRDirFlags)(PR_SKIP_BOTH | PR_SKIP_HIDDEN)))) { + while((entry = + PR_ReadDir(dir, (PRDirFlags)(PR_SKIP_BOTH | PR_SKIP_HIDDEN)))) { char *fullpath = aprintf("%s/%s", capath, entry->name); if(!fullpath) { PR_CloseDir(dir); @@ -1782,7 +1782,7 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl, CURLcode curlerr) { PRErrorCode err = 0; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; if(is_nss_error(curlerr)) { /* read NSPR error code */ @@ -1798,7 +1798,7 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl, } /* cleanup on connection failure */ - Curl_llist_destroy(&backend->obj_list, NULL); + Curl_llist_destroy(&backend->obj_list, NULL); return curlerr; } @@ -1809,11 +1809,11 @@ static CURLcode nss_set_blocking(struct ssl_connect_data *connssl, bool blocking) { static PRSocketOptionData sock_opt; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; sock_opt.option = PR_SockOpt_Nonblocking; sock_opt.value.non_blocking = !blocking; - if(PR_SetSocketOption(backend->handle, &sock_opt) != PR_SUCCESS) + if(PR_SetSocketOption(backend->handle, &sock_opt) != PR_SUCCESS) return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR); return CURLE_OK; @@ -1829,7 +1829,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) struct Curl_easy *data = conn->data; curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; CURLcode result; bool second_layer = FALSE; SSLVersionRange sslver_supported; @@ -1847,10 +1847,10 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) #endif }; - backend->data = data; + backend->data = data; /* list of all NSS objects we need to destroy in Curl_nss_close() */ - Curl_llist_init(&backend->obj_list, nss_destroy_object); + Curl_llist_init(&backend->obj_list, nss_destroy_object); PR_Lock(nss_initlock); result = nss_init(conn->data); @@ -1937,7 +1937,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) goto error; /* not checked yet */ - SSL_SET_OPTION_LVALUE(certverifyresult) = 0; + SSL_SET_OPTION_LVALUE(certverifyresult) = 0; if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess) goto error; @@ -1965,15 +1965,15 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) infof(data, " CRLfile: %s\n", SSL_SET_OPTION(CRLfile)); } - if(SSL_SET_OPTION(primary.clientcert)) { - char *nickname = dup_nickname(data, SSL_SET_OPTION(primary.clientcert)); + if(SSL_SET_OPTION(primary.clientcert)) { + char *nickname = dup_nickname(data, SSL_SET_OPTION(primary.clientcert)); if(nickname) { /* we are not going to use libnsspem.so to read the client cert */ - backend->obj_clicert = NULL; + backend->obj_clicert = NULL; } else { - CURLcode rv = cert_stuff(conn, sockindex, - SSL_SET_OPTION(primary.clientcert), + CURLcode rv = cert_stuff(conn, sockindex, + SSL_SET_OPTION(primary.clientcert), SSL_SET_OPTION(key)); if(rv) { /* failf() is already done in cert_stuff() */ @@ -1983,10 +1983,10 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) } /* store the nickname for SelectClientCert() called during handshake */ - backend->client_nickname = nickname; + backend->client_nickname = nickname; } else - backend->client_nickname = NULL; + backend->client_nickname = NULL; if(SSL_GetClientAuthDataHook(model, SelectClientCert, (void *)connssl) != SECSuccess) { @@ -1994,14 +1994,14 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) goto error; } -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY if(conn->proxy_ssl[sockindex].use) { DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state); DEBUGASSERT(conn->proxy_ssl[sockindex].backend->handle != NULL); nspr_io = conn->proxy_ssl[sockindex].backend->handle; second_layer = TRUE; } -#endif +#endif else { /* wrap OS file descriptor by NSPR's file descriptor abstraction */ nspr_io = PR_ImportTCPSocket(sockfd); @@ -2029,8 +2029,8 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) } /* import our model socket onto the current I/O stack */ - backend->handle = SSL_ImportFD(model, nspr_io); - if(!backend->handle) { + backend->handle = SSL_ImportFD(model, nspr_io); + if(!backend->handle) { if(!second_layer) PR_Close(nspr_io); goto error; @@ -2041,36 +2041,36 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) /* This is the password associated with the cert that we're using */ if(SSL_SET_OPTION(key_passwd)) { - SSL_SetPKCS11PinArg(backend->handle, SSL_SET_OPTION(key_passwd)); + SSL_SetPKCS11PinArg(backend->handle, SSL_SET_OPTION(key_passwd)); } #ifdef SSL_ENABLE_OCSP_STAPLING if(SSL_CONN_CONFIG(verifystatus)) { - if(SSL_OptionSet(backend->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE) + if(SSL_OptionSet(backend->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE) != SECSuccess) goto error; } #endif #ifdef SSL_ENABLE_NPN - if(SSL_OptionSet(backend->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn + if(SSL_OptionSet(backend->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn ? PR_TRUE : PR_FALSE) != SECSuccess) goto error; #endif #ifdef SSL_ENABLE_ALPN - if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn + if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn ? PR_TRUE : PR_FALSE) != SECSuccess) goto error; #endif #if NSSVERNUM >= 0x030f04 /* 3.15.4 */ if(data->set.ssl.falsestart) { - if(SSL_OptionSet(backend->handle, SSL_ENABLE_FALSE_START, PR_TRUE) + if(SSL_OptionSet(backend->handle, SSL_ENABLE_FALSE_START, PR_TRUE) != SECSuccess) goto error; - if(SSL_SetCanFalseStartCallback(backend->handle, CanFalseStartCallback, + if(SSL_SetCanFalseStartCallback(backend->handle, CanFalseStartCallback, conn) != SECSuccess) goto error; } @@ -2082,11 +2082,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) unsigned char protocols[128]; #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 -#ifndef CURL_DISABLE_PROXY - && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) -#endif - ) { + if(data->set.httpversion >= CURL_HTTP_VERSION_2 +#ifndef CURL_DISABLE_PROXY + && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) +#endif + ) { protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN); @@ -2097,23 +2097,23 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); cur += ALPN_HTTP_1_1_LENGTH; - if(SSL_SetNextProtoNego(backend->handle, protocols, cur) != SECSuccess) + if(SSL_SetNextProtoNego(backend->handle, protocols, cur) != SECSuccess) goto error; } #endif /* Force handshake on next I/O */ - if(SSL_ResetHandshake(backend->handle, /* asServer */ PR_FALSE) + if(SSL_ResetHandshake(backend->handle, /* asServer */ PR_FALSE) != SECSuccess) goto error; /* propagate hostname to the TLS layer */ - if(SSL_SetURL(backend->handle, SSL_HOST_NAME()) != SECSuccess) + if(SSL_SetURL(backend->handle, SSL_HOST_NAME()) != SECSuccess) goto error; /* prevent NSS from re-using the session for a different hostname */ - if(SSL_SetSockPeerID(backend->handle, SSL_HOST_NAME()) != SECSuccess) + if(SSL_SetSockPeerID(backend->handle, SSL_HOST_NAME()) != SECSuccess) goto error; return CURLE_OK; @@ -2128,13 +2128,13 @@ error: static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; struct Curl_easy *data = conn->data; CURLcode result = CURLE_SSL_CONNECT_ERROR; PRUint32 timeout; /* check timeout situation */ - const timediff_t time_left = Curl_timeleft(data, NULL, TRUE); + const timediff_t time_left = Curl_timeleft(data, NULL, TRUE); if(time_left < 0) { failf(data, "timed out before SSL handshake"); result = CURLE_OPERATION_TIMEDOUT; @@ -2143,18 +2143,18 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) /* Force the handshake now */ timeout = PR_MillisecondsToInterval((PRUint32) time_left); - if(SSL_ForceHandshakeWithTimeout(backend->handle, timeout) != SECSuccess) { + if(SSL_ForceHandshakeWithTimeout(backend->handle, timeout) != SECSuccess) { if(PR_GetError() == PR_WOULD_BLOCK_ERROR) /* blocking direction is updated by nss_update_connecting_state() */ return CURLE_AGAIN; - else if(SSL_SET_OPTION(certverifyresult) == SSL_ERROR_BAD_CERT_DOMAIN) + else if(SSL_SET_OPTION(certverifyresult) == SSL_ERROR_BAD_CERT_DOMAIN) result = CURLE_PEER_FAILED_VERIFICATION; - else if(SSL_SET_OPTION(certverifyresult) != 0) + else if(SSL_SET_OPTION(certverifyresult) != 0) result = CURLE_PEER_FAILED_VERIFICATION; goto error; } - result = display_conn_info(conn, backend->handle); + result = display_conn_info(conn, backend->handle); if(result) goto error; @@ -2163,7 +2163,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert)); if(nickname) { /* we support only nicknames in case of issuercert for now */ - ret = check_issuer_cert(backend->handle, nickname); + ret = check_issuer_cert(backend->handle, nickname); free(nickname); } @@ -2177,7 +2177,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) } } - result = cmp_peer_pubkey(connssl, SSL_PINNED_PUB_KEY()); + result = cmp_peer_pubkey(connssl, SSL_PINNED_PUB_KEY()); if(result) /* status already printed */ goto error; @@ -2267,14 +2267,14 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */ CURLcode *curlcode) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; ssize_t rc; /* The SelectClientCert() hook uses this for infof() and failf() but the handle stored in nss_setup_connect() could have already been freed. */ - backend->data = conn->data; + backend->data = conn->data; - rc = PR_Send(backend->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT); + rc = PR_Send(backend->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT); if(rc < 0) { PRInt32 err = PR_GetError(); if(err == PR_WOULD_BLOCK_ERROR) @@ -2305,14 +2305,14 @@ static ssize_t nss_recv(struct connectdata *conn, /* connection data */ CURLcode *curlcode) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; ssize_t nread; /* The SelectClientCert() hook uses this for infof() and failf() but the handle stored in nss_setup_connect() could have already been freed. */ - backend->data = conn->data; + backend->data = conn->data; - nread = PR_Recv(backend->handle, buf, (int)buffersize, 0, + nread = PR_Recv(backend->handle, buf, (int)buffersize, 0, PR_INTERVAL_NO_WAIT); if(nread < 0) { /* failed SSL read */ @@ -2373,9 +2373,9 @@ static CURLcode Curl_nss_md5sum(unsigned char *tmp, /* input */ PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5); unsigned int MD5out; - if(!MD5pw) - return CURLE_NOT_BUILT_IN; - + if(!MD5pw) + return CURLE_NOT_BUILT_IN; + PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen)); PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len)); PK11_DestroyContext(MD5pw, PR_TRUE); @@ -2391,9 +2391,9 @@ static CURLcode Curl_nss_sha256sum(const unsigned char *tmp, /* input */ PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256); unsigned int SHA256out; - if(!SHA256pw) - return CURLE_NOT_BUILT_IN; - + if(!SHA256pw) + return CURLE_NOT_BUILT_IN; + PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen)); PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len)); PK11_DestroyContext(SHA256pw, PR_TRUE); @@ -2422,9 +2422,9 @@ static bool Curl_nss_false_start(void) static void *Curl_nss_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) { - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; (void)info; - return backend->handle; + return backend->handle; } const struct Curl_ssl Curl_ssl_nss = { diff --git a/contrib/libs/curl/lib/vtls/nssg.h b/contrib/libs/curl/lib/vtls/nssg.h index 37b364647b..63a607bec0 100644 --- a/contrib/libs/curl/lib/vtls/nssg.h +++ b/contrib/libs/curl/lib/vtls/nssg.h @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is diff --git a/contrib/libs/curl/lib/vtls/openssl.c b/contrib/libs/curl/lib/vtls/openssl.c index e9c535f8f4..3dd9d62ca5 100644 --- a/contrib/libs/curl/lib/vtls/openssl.c +++ b/contrib/libs/curl/lib/vtls/openssl.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -31,18 +31,18 @@ #include <limits.h> -/* Wincrypt must be included before anything that could include OpenSSL. */ -#if defined(USE_WIN32_CRYPTO) -#include <wincrypt.h> -/* Undefine wincrypt conflicting symbols for BoringSSL. */ -#undef X509_NAME -#undef X509_EXTENSIONS -#undef PKCS7_ISSUER_AND_SERIAL -#undef PKCS7_SIGNER_INFO -#undef OCSP_REQUEST -#undef OCSP_RESPONSE -#endif - +/* Wincrypt must be included before anything that could include OpenSSL. */ +#if defined(USE_WIN32_CRYPTO) +#include <wincrypt.h> +/* Undefine wincrypt conflicting symbols for BoringSSL. */ +#undef X509_NAME +#undef X509_EXTENSIONS +#undef PKCS7_ISSUER_AND_SERIAL +#undef PKCS7_SIGNER_INFO +#undef OCSP_REQUEST +#undef OCSP_RESPONSE +#endif + #include "urldata.h" #include "sendf.h" #include "formdata.h" /* for the boundary function */ @@ -53,13 +53,13 @@ #include "slist.h" #include "select.h" #include "vtls.h" -#include "keylog.h" +#include "keylog.h" #include "strcase.h" #include "hostcheck.h" #include "multiif.h" -#include "strerror.h" +#include "strerror.h" #include "curl_printf.h" - + #include <openssl/ssl.h> #include <openssl/rand.h> #include <openssl/x509v3.h> @@ -200,10 +200,10 @@ !defined(OPENSSL_IS_BORINGSSL)) #define HAVE_SSL_CTX_SET_CIPHERSUITES #define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH -/* SET_EC_CURVES available under the same preconditions: see - * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html - */ -#define HAVE_SSL_CTX_SET_EC_CURVES +/* SET_EC_CURVES available under the same preconditions: see + * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html + */ +#define HAVE_SSL_CTX_SET_EC_CURVES #endif #if defined(LIBRESSL_VERSION_NUMBER) @@ -225,22 +225,22 @@ "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH" #endif -#ifdef HAVE_OPENSSL_SRP -/* the function exists */ -#ifdef USE_TLS_SRP -/* the functionality is not disabled */ -#define USE_OPENSSL_SRP -#endif -#endif +#ifdef HAVE_OPENSSL_SRP +/* the function exists */ +#ifdef USE_TLS_SRP +/* the functionality is not disabled */ +#define USE_OPENSSL_SRP +#endif +#endif struct ssl_backend_data { /* these ones requires specific SSL-types */ SSL_CTX* ctx; SSL* handle; X509* server_cert; -#ifndef HAVE_KEYLOG_CALLBACK - /* Set to true once a valid keylog entry has been created to avoid dupes. */ - bool keylog_done; +#ifndef HAVE_KEYLOG_CALLBACK + /* Set to true once a valid keylog entry has been created to avoid dupes. */ + bool keylog_done; #endif }; @@ -257,22 +257,22 @@ static void ossl_keylog_callback(const SSL *ssl, const char *line) { (void)ssl; - Curl_tls_keylog_write_line(line); + Curl_tls_keylog_write_line(line); } #else /* - * ossl_log_tls12_secret is called by libcurl to make the CLIENT_RANDOMs if the - * OpenSSL being used doesn't have native support for doing that. + * ossl_log_tls12_secret is called by libcurl to make the CLIENT_RANDOMs if the + * OpenSSL being used doesn't have native support for doing that. */ -static void -ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done) +static void +ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done) { const SSL_SESSION *session = SSL_get_session(ssl); unsigned char client_random[SSL3_RANDOM_SIZE]; unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; int master_key_length = 0; - if(!session || *keylog_done) + if(!session || *keylog_done) return; #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ @@ -291,15 +291,15 @@ ossl_log_tls12_secret(const SSL *ssl, bool *keylog_done) } #endif - /* The handshake has not progressed sufficiently yet, or this is a TLS 1.3 - * session (when curl was built with older OpenSSL headers and running with - * newer OpenSSL runtime libraries). */ + /* The handshake has not progressed sufficiently yet, or this is a TLS 1.3 + * session (when curl was built with older OpenSSL headers and running with + * newer OpenSSL runtime libraries). */ if(master_key_length <= 0) return; - *keylog_done = true; - Curl_tls_keylog_write("CLIENT_RANDOM", client_random, - master_key, master_key_length); + *keylog_done = true; + Curl_tls_keylog_write("CLIENT_RANDOM", client_random, + master_key, master_key_length); } #endif /* !HAVE_KEYLOG_CALLBACK */ @@ -345,20 +345,20 @@ static const char *SSL_ERROR_to_str(int err) */ static char *ossl_strerror(unsigned long error, char *buf, size_t size) { - if(size) - *buf = '\0'; - + if(size) + *buf = '\0'; + #ifdef OPENSSL_IS_BORINGSSL ERR_error_string_n((uint32_t)error, buf, size); #else ERR_error_string_n(error, buf, size); #endif - - if(size > 1 && !*buf) { - strncpy(buf, (error ? "Unknown error" : "No error"), size); - buf[size - 1] = '\0'; - } - + + if(size > 1 && !*buf) { + strncpy(buf, (error ? "Unknown error" : "No error"), size); + buf[size - 1] = '\0'; + } + return buf; } @@ -575,138 +575,138 @@ static bool is_pkcs11_uri(const char *string) static CURLcode Curl_ossl_set_engine(struct Curl_easy *data, const char *engine); -static int -SSL_CTX_use_certificate_bio(SSL_CTX *ctx, BIO *in, int type, - const char *key_passwd) -{ - int ret = 0; - X509 *x = NULL; - - if(type == SSL_FILETYPE_ASN1) { - /* j = ERR_R_ASN1_LIB; */ - x = d2i_X509_bio(in, NULL); - } - else if(type == SSL_FILETYPE_PEM) { - /* ERR_R_PEM_LIB; */ - x = PEM_read_bio_X509(in, NULL, - passwd_callback, (void *)key_passwd); - } - else { - ret = 0; - goto end; - } - - if(x == NULL) { - ret = 0; - goto end; - } - - ret = SSL_CTX_use_certificate(ctx, x); - end: - X509_free(x); - return ret; -} - -static int -SSL_CTX_use_PrivateKey_bio(SSL_CTX *ctx, BIO* in, int type, - const char *key_passwd) -{ - int ret = 0; - EVP_PKEY *pkey = NULL; - - if(type == SSL_FILETYPE_PEM) - pkey = PEM_read_bio_PrivateKey(in, NULL, passwd_callback, - (void *)key_passwd); - else if(type == SSL_FILETYPE_ASN1) - pkey = d2i_PrivateKey_bio(in, NULL); - else { - ret = 0; - goto end; - } - if(pkey == NULL) { - ret = 0; - goto end; - } - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); - end: - return ret; -} - -static int -SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO* in, - const char *key_passwd) -{ -/* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ -#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* OpenSSL 1.0.2 or later */ \ - !(defined(LIBRESSL_VERSION_NUMBER) && \ - (LIBRESSL_VERSION_NUMBER < 0x2090100fL)) /* LibreSSL 2.9.1 or later */ - int ret = 0; - X509 *x = NULL; - void *passwd_callback_userdata = (void *)key_passwd; - - ERR_clear_error(); - - x = PEM_read_bio_X509_AUX(in, NULL, - passwd_callback, (void *)key_passwd); - - if(x == NULL) { - ret = 0; - goto end; - } - - ret = SSL_CTX_use_certificate(ctx, x); - - if(ERR_peek_error() != 0) - ret = 0; - - if(ret) { - X509 *ca; - unsigned long err; - - if(!SSL_CTX_clear_chain_certs(ctx)) { - ret = 0; - goto end; - } - - while((ca = PEM_read_bio_X509(in, NULL, passwd_callback, - passwd_callback_userdata)) - != NULL) { - - if(!SSL_CTX_add0_chain_cert(ctx, ca)) { - X509_free(ca); - ret = 0; - goto end; - } - } - - err = ERR_peek_last_error(); - if((ERR_GET_LIB(err) == ERR_LIB_PEM) && - (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) - ERR_clear_error(); - else - ret = 0; - } - - end: - X509_free(x); - return ret; -#else - (void)ctx; /* unused */ - (void)in; /* unused */ - (void)key_passwd; /* unused */ - return 0; -#endif -} - +static int +SSL_CTX_use_certificate_bio(SSL_CTX *ctx, BIO *in, int type, + const char *key_passwd) +{ + int ret = 0; + X509 *x = NULL; + + if(type == SSL_FILETYPE_ASN1) { + /* j = ERR_R_ASN1_LIB; */ + x = d2i_X509_bio(in, NULL); + } + else if(type == SSL_FILETYPE_PEM) { + /* ERR_R_PEM_LIB; */ + x = PEM_read_bio_X509(in, NULL, + passwd_callback, (void *)key_passwd); + } + else { + ret = 0; + goto end; + } + + if(x == NULL) { + ret = 0; + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + end: + X509_free(x); + return ret; +} + +static int +SSL_CTX_use_PrivateKey_bio(SSL_CTX *ctx, BIO* in, int type, + const char *key_passwd) +{ + int ret = 0; + EVP_PKEY *pkey = NULL; + + if(type == SSL_FILETYPE_PEM) + pkey = PEM_read_bio_PrivateKey(in, NULL, passwd_callback, + (void *)key_passwd); + else if(type == SSL_FILETYPE_ASN1) + pkey = d2i_PrivateKey_bio(in, NULL); + else { + ret = 0; + goto end; + } + if(pkey == NULL) { + ret = 0; + goto end; + } + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + end: + return ret; +} + +static int +SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO* in, + const char *key_passwd) +{ +/* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ +#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* OpenSSL 1.0.2 or later */ \ + !(defined(LIBRESSL_VERSION_NUMBER) && \ + (LIBRESSL_VERSION_NUMBER < 0x2090100fL)) /* LibreSSL 2.9.1 or later */ + int ret = 0; + X509 *x = NULL; + void *passwd_callback_userdata = (void *)key_passwd; + + ERR_clear_error(); + + x = PEM_read_bio_X509_AUX(in, NULL, + passwd_callback, (void *)key_passwd); + + if(x == NULL) { + ret = 0; + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + + if(ERR_peek_error() != 0) + ret = 0; + + if(ret) { + X509 *ca; + unsigned long err; + + if(!SSL_CTX_clear_chain_certs(ctx)) { + ret = 0; + goto end; + } + + while((ca = PEM_read_bio_X509(in, NULL, passwd_callback, + passwd_callback_userdata)) + != NULL) { + + if(!SSL_CTX_add0_chain_cert(ctx, ca)) { + X509_free(ca); + ret = 0; + goto end; + } + } + + err = ERR_peek_last_error(); + if((ERR_GET_LIB(err) == ERR_LIB_PEM) && + (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) + ERR_clear_error(); + else + ret = 0; + } + + end: + X509_free(x); + return ret; +#else + (void)ctx; /* unused */ + (void)in; /* unused */ + (void)key_passwd; /* unused */ + return 0; +#endif +} + static int cert_stuff(struct connectdata *conn, SSL_CTX* ctx, char *cert_file, - BIO *cert_bio, + BIO *cert_bio, const char *cert_type, char *key_file, - BIO* key_bio, + BIO* key_bio, const char *key_type, char *key_passwd) { @@ -716,11 +716,11 @@ int cert_stuff(struct connectdata *conn, int file_type = do_file_type(cert_type); - if(cert_file || cert_bio || (file_type == SSL_FILETYPE_ENGINE)) { + if(cert_file || cert_bio || (file_type == SSL_FILETYPE_ENGINE)) { SSL *ssl; X509 *x509; int cert_done = 0; - int cert_use_result; + int cert_use_result; if(key_passwd) { /* set the password in the callback userdata */ @@ -733,10 +733,10 @@ int cert_stuff(struct connectdata *conn, switch(file_type) { case SSL_FILETYPE_PEM: /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ - cert_use_result = cert_bio ? - SSL_CTX_use_certificate_chain_bio(ctx, cert_bio, key_passwd) : - SSL_CTX_use_certificate_chain_file(ctx, cert_file); - if(cert_use_result != 1) { + cert_use_result = cert_bio ? + SSL_CTX_use_certificate_chain_bio(ctx, cert_bio, key_passwd) : + SSL_CTX_use_certificate_chain_file(ctx, cert_file); + if(cert_use_result != 1) { failf(data, "could not load PEM client certificate, " OSSL_PACKAGE " error %s, " @@ -751,12 +751,12 @@ int cert_stuff(struct connectdata *conn, /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but we use the case above for PEM so this can only be performed with ASN1 files. */ - - cert_use_result = cert_bio ? - SSL_CTX_use_certificate_bio(ctx, cert_bio, - file_type, key_passwd) : - SSL_CTX_use_certificate_file(ctx, cert_file, file_type); - if(cert_use_result != 1) { + + cert_use_result = cert_bio ? + SSL_CTX_use_certificate_bio(ctx, cert_bio, + file_type, key_passwd) : + SSL_CTX_use_certificate_file(ctx, cert_file, file_type); + if(cert_use_result != 1) { failf(data, "could not load ASN1 client certificate, " OSSL_PACKAGE " error %s, " @@ -836,31 +836,31 @@ int cert_stuff(struct connectdata *conn, PKCS12 *p12 = NULL; EVP_PKEY *pri; STACK_OF(X509) *ca = NULL; - if(!cert_bio) { - fp = BIO_new(BIO_s_file()); - if(fp == NULL) { - failf(data, - "BIO_new return NULL, " OSSL_PACKAGE - " error %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer)) ); - return 0; - } - - if(BIO_read_filename(fp, cert_file) <= 0) { - failf(data, "could not open PKCS12 file '%s'", cert_file); - BIO_free(fp); - return 0; - } + if(!cert_bio) { + fp = BIO_new(BIO_s_file()); + if(fp == NULL) { + failf(data, + "BIO_new return NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + return 0; + } + + if(BIO_read_filename(fp, cert_file) <= 0) { + failf(data, "could not open PKCS12 file '%s'", cert_file); + BIO_free(fp); + return 0; + } } - p12 = d2i_PKCS12_bio(cert_bio ? cert_bio : fp, NULL); - if(fp) + p12 = d2i_PKCS12_bio(cert_bio ? cert_bio : fp, NULL); + if(fp) BIO_free(fp); if(!p12) { - failf(data, "error reading PKCS12 file '%s'", - cert_bio ? "(memory blob)" : cert_file); + failf(data, "error reading PKCS12 file '%s'", + cert_bio ? "(memory blob)" : cert_file); return 0; } @@ -941,10 +941,10 @@ int cert_stuff(struct connectdata *conn, return 0; } - if((!key_file) && (!key_bio)) { + if((!key_file) && (!key_bio)) { key_file = cert_file; - key_bio = cert_bio; - } + key_bio = cert_bio; + } else file_type = do_file_type(key_type); @@ -954,12 +954,12 @@ int cert_stuff(struct connectdata *conn, break; /* FALLTHROUGH */ case SSL_FILETYPE_ASN1: - cert_use_result = key_bio ? - SSL_CTX_use_PrivateKey_bio(ctx, key_bio, file_type, key_passwd) : - SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type); - if(cert_use_result != 1) { + cert_use_result = key_bio ? + SSL_CTX_use_PrivateKey_bio(ctx, key_bio, file_type, key_passwd) : + SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type); + if(cert_use_result != 1) { failf(data, "unable to set private key file: '%s' type %s", - key_file?key_file:"(memory blob)", key_type?key_type:"PEM"); + key_file?key_file:"(memory blob)", key_type?key_type:"PEM"); return 0; } break; @@ -1115,21 +1115,21 @@ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size) */ static int Curl_ossl_init(void) { -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ - !defined(LIBRESSL_VERSION_NUMBER) - const uint64_t flags = -#ifdef OPENSSL_INIT_ENGINE_ALL_BUILTIN - /* not present in BoringSSL */ - OPENSSL_INIT_ENGINE_ALL_BUILTIN | -#endif -#ifdef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG - OPENSSL_INIT_NO_LOAD_CONFIG | -#else - OPENSSL_INIT_LOAD_CONFIG | -#endif - 0; - OPENSSL_init_ssl(flags, NULL); -#else +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ + !defined(LIBRESSL_VERSION_NUMBER) + const uint64_t flags = +#ifdef OPENSSL_INIT_ENGINE_ALL_BUILTIN + /* not present in BoringSSL */ + OPENSSL_INIT_ENGINE_ALL_BUILTIN | +#endif +#ifdef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG + OPENSSL_INIT_NO_LOAD_CONFIG | +#else + OPENSSL_INIT_LOAD_CONFIG | +#endif + 0; + OPENSSL_init_ssl(flags, NULL); +#else OPENSSL_load_builtin_modules(); #ifdef USE_OPENSSL_ENGINE @@ -1158,7 +1158,7 @@ static int Curl_ossl_init(void) OpenSSL_add_all_algorithms(); #endif - Curl_tls_keylog_open(); + Curl_tls_keylog_open(); /* Initialize the extra data indexes */ if(ossl_get_ssl_conn_index() < 0 || ossl_get_ssl_sockindex_index() < 0) @@ -1201,7 +1201,7 @@ static void Curl_ossl_cleanup(void) #endif #endif - Curl_tls_keylog_close(); + Curl_tls_keylog_close(); } /* @@ -1348,17 +1348,17 @@ static struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data) static void ossl_close(struct ssl_connect_data *connssl) { - struct ssl_backend_data *backend = connssl->backend; - if(backend->handle) { - (void)SSL_shutdown(backend->handle); - SSL_set_connect_state(backend->handle); + struct ssl_backend_data *backend = connssl->backend; + if(backend->handle) { + (void)SSL_shutdown(backend->handle); + SSL_set_connect_state(backend->handle); - SSL_free(backend->handle); - backend->handle = NULL; + 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; } } @@ -1368,9 +1368,9 @@ static void ossl_close(struct ssl_connect_data *connssl) static void Curl_ossl_close(struct connectdata *conn, int sockindex) { ossl_close(&conn->ssl[sockindex]); -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY ossl_close(&conn->proxy_ssl[sockindex]); -#endif +#endif } /* @@ -1389,7 +1389,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) int buffsize; int err; bool done = FALSE; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; #ifndef CURL_DISABLE_FTP /* This has only been tested on the proftpd server, and the mod_tls code @@ -1398,10 +1398,10 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) we do not send one. Let's hope other servers do the same... */ if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) - (void)SSL_shutdown(backend->handle); + (void)SSL_shutdown(backend->handle); #endif - if(backend->handle) { + if(backend->handle) { buffsize = (int)sizeof(buf); while(!done) { int what = SOCKET_READABLE(conn->sock[sockindex], @@ -1411,8 +1411,8 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) /* Something to read, let's do it and hope that it is the close notify alert from the server */ - nread = (ssize_t)SSL_read(backend->handle, buf, buffsize); - err = SSL_get_error(backend->handle, (int)nread); + nread = (ssize_t)SSL_read(backend->handle, buf, buffsize); + err = SSL_get_error(backend->handle, (int)nread); switch(err) { case SSL_ERROR_NONE: /* this is not an error */ @@ -1457,7 +1457,7 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) if(data->set.verbose) { #ifdef HAVE_SSL_GET_SHUTDOWN - switch(SSL_get_shutdown(backend->handle)) { + switch(SSL_get_shutdown(backend->handle)) { case SSL_SENT_SHUTDOWN: infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n"); break; @@ -1472,8 +1472,8 @@ static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) #endif } - SSL_free(backend->handle); - backend->handle = NULL; + SSL_free(backend->handle); + backend->handle = NULL; } return retval; } @@ -1597,8 +1597,8 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) CURLcode result = CURLE_OK; bool dNSName = FALSE; /* if a dNSName field exists in the cert */ bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */ - const char * const hostname = SSL_HOST_NAME(); - const char * const dispname = SSL_HOST_DISPNAME(); + const char * const hostname = SSL_HOST_NAME(); + const char * const dispname = SSL_HOST_DISPNAME(); #ifdef ENABLE_IPV6 if(conn->bits.ipv6_ip && @@ -1656,7 +1656,7 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) type itself: for example for an IA5String the data will be ASCII" It has been however verified that in 0.9.6 and 0.9.7, IA5String - is always null-terminated. + is always null-terminated. */ if((altlen == strlen(altptr)) && /* if this isn't true, there was an embedded zero in the name @@ -1794,14 +1794,14 @@ static CURLcode verifystatus(struct connectdata *conn, OCSP_BASICRESP *br = NULL; X509_STORE *st = NULL; STACK_OF(X509) *ch = NULL; - struct ssl_backend_data *backend = connssl->backend; - X509 *cert; - OCSP_CERTID *id = NULL; - int cert_status, crl_reason; - ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; - int ret; + struct ssl_backend_data *backend = connssl->backend; + X509 *cert; + OCSP_CERTID *id = NULL; + int cert_status, crl_reason; + ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; + int ret; - long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status); + long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status); if(!status) { failf(data, "No OCSP response received"); @@ -1831,8 +1831,8 @@ static CURLcode verifystatus(struct connectdata *conn, goto end; } - ch = SSL_get_peer_cert_chain(backend->handle); - st = SSL_CTX_get_cert_store(backend->ctx); + ch = SSL_get_peer_cert_chain(backend->handle); + st = SSL_CTX_get_cert_store(backend->ctx); #if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \ (defined(LIBRESSL_VERSION_NUMBER) && \ @@ -1868,68 +1868,68 @@ static CURLcode verifystatus(struct connectdata *conn, goto end; } - /* Compute the certificate's ID */ - cert = SSL_get_peer_certificate(backend->handle); - if(!cert) { - failf(data, "Error getting peer certficate"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - for(i = 0; i < sk_X509_num(ch); i++) { - X509 *issuer = sk_X509_value(ch, i); - if(X509_check_issued(issuer, cert) == X509_V_OK) { - id = OCSP_cert_to_id(EVP_sha1(), cert, issuer); - break; - } - } - X509_free(cert); - - if(!id) { - failf(data, "Error computing OCSP ID"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - /* Find the single OCSP response corresponding to the certificate ID */ - ret = OCSP_resp_find_status(br, id, &cert_status, &crl_reason, &rev, - &thisupd, &nextupd); - OCSP_CERTID_free(id); - if(ret != 1) { - failf(data, "Could not find certificate ID in OCSP response"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - /* Validate the corresponding single OCSP response */ - if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { - failf(data, "OCSP response has expired"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - infof(data, "SSL certificate status: %s (%d)\n", - OCSP_cert_status_str(cert_status), cert_status); - - switch(cert_status) { - case V_OCSP_CERTSTATUS_GOOD: - break; - - case V_OCSP_CERTSTATUS_REVOKED: - result = CURLE_SSL_INVALIDCERTSTATUS; - failf(data, "SSL certificate revocation reason: %s (%d)", - OCSP_crl_reason_str(crl_reason), crl_reason); - goto end; - - case V_OCSP_CERTSTATUS_UNKNOWN: - default: - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; + /* Compute the certificate's ID */ + cert = SSL_get_peer_certificate(backend->handle); + if(!cert) { + failf(data, "Error getting peer certficate"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + + for(i = 0; i < sk_X509_num(ch); i++) { + X509 *issuer = sk_X509_value(ch, i); + if(X509_check_issued(issuer, cert) == X509_V_OK) { + id = OCSP_cert_to_id(EVP_sha1(), cert, issuer); + break; + } + } + X509_free(cert); + + if(!id) { + failf(data, "Error computing OCSP ID"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + + /* Find the single OCSP response corresponding to the certificate ID */ + ret = OCSP_resp_find_status(br, id, &cert_status, &crl_reason, &rev, + &thisupd, &nextupd); + OCSP_CERTID_free(id); + if(ret != 1) { + failf(data, "Could not find certificate ID in OCSP response"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + + /* Validate the corresponding single OCSP response */ + if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { + failf(data, "OCSP response has expired"); + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; + } + + infof(data, "SSL certificate status: %s (%d)\n", + OCSP_cert_status_str(cert_status), cert_status); + + switch(cert_status) { + case V_OCSP_CERTSTATUS_GOOD: + break; + + case V_OCSP_CERTSTATUS_REVOKED: + result = CURLE_SSL_INVALIDCERTSTATUS; + failf(data, "SSL certificate revocation reason: %s (%d)", + OCSP_crl_reason_str(crl_reason), crl_reason); + goto end; + + case V_OCSP_CERTSTATUS_UNKNOWN: + default: + result = CURLE_SSL_INVALIDCERTSTATUS; + goto end; } end: - if(br) - OCSP_BASICRESP_free(br); + if(br) + OCSP_BASICRESP_free(br); OCSP_RESPONSE_free(rsp); return result; @@ -2275,13 +2275,13 @@ set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn) long curl_ssl_version_max; /* convert cURL min SSL version option to OpenSSL constant */ -#if defined(OPENSSL_IS_BORINGSSL) || defined(LIBRESSL_VERSION_NUMBER) - uint16_t ossl_ssl_version_min = 0; - uint16_t ossl_ssl_version_max = 0; -#else +#if defined(OPENSSL_IS_BORINGSSL) || defined(LIBRESSL_VERSION_NUMBER) + uint16_t ossl_ssl_version_min = 0; + uint16_t ossl_ssl_version_max = 0; +#else long ossl_ssl_version_min = 0; long ossl_ssl_version_max = 0; -#endif +#endif switch(curl_ssl_version_min) { case CURL_SSLVERSION_TLSv1: /* TLS 1.x */ case CURL_SSLVERSION_TLSv1_0: @@ -2301,10 +2301,10 @@ set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn) } /* CURL_SSLVERSION_DEFAULT means that no option was selected. - We don't want to pass 0 to SSL_CTX_set_min_proto_version as - it would enable all versions down to the lowest supported by - the library. - So we skip this, and stay with the OS default + We don't want to pass 0 to SSL_CTX_set_min_proto_version as + it would enable all versions down to the lowest supported by + the library. + So we skip this, and stay with the OS default */ if(curl_ssl_version_min != CURL_SSLVERSION_DEFAULT) { if(!SSL_CTX_set_min_proto_version(ctx, ossl_ssl_version_min)) { @@ -2374,7 +2374,7 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options, #ifdef TLS1_3_VERSION { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION); + SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION); *ctx_options |= SSL_OP_NO_TLSv1_2; } #else @@ -2502,8 +2502,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME bool sni; - const char * const hostname = SSL_HOST_NAME(); - + const char * const hostname = SSL_HOST_NAME(); + #ifdef ENABLE_IPV6 struct in6_addr addr; #else @@ -2511,19 +2511,19 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) #endif #endif const long int ssl_version = SSL_CONN_CONFIG(version); -#ifdef USE_OPENSSL_SRP +#ifdef USE_OPENSSL_SRP const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype); #endif - char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); - const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); + char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); + const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); const char * const ssl_cert_type = SSL_SET_OPTION(cert_type); const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); const char * const ssl_capath = SSL_CONN_CONFIG(CApath); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); char error_buffer[256]; - struct ssl_backend_data *backend = connssl->backend; - bool imported_native_ca = false; + struct ssl_backend_data *backend = connssl->backend; + bool imported_native_ca = false; DEBUGASSERT(ssl_connect_1 == connssl->connecting_state); @@ -2532,7 +2532,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) if(result) return result; - SSL_SET_OPTION_LVALUE(certverifyresult) = !X509_V_OK; + SSL_SET_OPTION_LVALUE(certverifyresult) = !X509_V_OK; /* check to see if we've been told to use an explicit SSL/TLS version */ @@ -2556,7 +2556,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) failf(data, OSSL_PACKAGE " was built without SSLv2 support"); return CURLE_NOT_BUILT_IN; #else -#ifdef USE_OPENSSL_SRP +#ifdef USE_OPENSSL_SRP if(ssl_authtype == CURL_TLSAUTH_SRP) return CURLE_SSL_CONNECT_ERROR; #endif @@ -2569,7 +2569,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) failf(data, OSSL_PACKAGE " was built without SSLv3 support"); return CURLE_NOT_BUILT_IN; #else -#ifdef USE_OPENSSL_SRP +#ifdef USE_OPENSSL_SRP if(ssl_authtype == CURL_TLSAUTH_SRP) return CURLE_SSL_CONNECT_ERROR; #endif @@ -2582,25 +2582,25 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) return CURLE_SSL_CONNECT_ERROR; } - 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: %s", ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer))); return CURLE_OUT_OF_MEMORY; } #ifdef SSL_MODE_RELEASE_BUFFERS - SSL_CTX_set_mode(backend->ctx, SSL_MODE_RELEASE_BUFFERS); + SSL_CTX_set_mode(backend->ctx, SSL_MODE_RELEASE_BUFFERS); #endif #ifdef SSL_CTRL_SET_MSG_CALLBACK if(data->set.fdebug && data->set.verbose) { /* the SSL trace callback is only used for verbose logging */ - SSL_CTX_set_msg_callback(backend->ctx, ssl_tls_trace); - SSL_CTX_set_msg_callback_arg(backend->ctx, conn); + SSL_CTX_set_msg_callback(backend->ctx, ssl_tls_trace); + SSL_CTX_set_msg_callback_arg(backend->ctx, conn); } #endif @@ -2666,8 +2666,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* "--sslv2" option means SSLv2 only, disable all others */ case CURL_SSLVERSION_SSLv2: #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ - SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION); - SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION); + SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION); + SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION); #else ctx_options |= SSL_OP_NO_SSLv3; ctx_options |= SSL_OP_NO_TLSv1; @@ -2684,8 +2684,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* "--sslv3" option means SSLv3 only, disable all others */ case CURL_SSLVERSION_SSLv3: #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ - SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION); - SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION); + SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION); + SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION); #else ctx_options |= SSL_OP_NO_SSLv2; ctx_options |= SSL_OP_NO_TLSv1; @@ -2712,7 +2712,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) ctx_options |= SSL_OP_NO_SSLv3; #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ - result = set_ssl_version_min_max(backend->ctx, conn); + result = set_ssl_version_min_max(backend->ctx, conn); #else result = set_ssl_version_min_max_legacy(&ctx_options, conn, sockindex); #endif @@ -2725,11 +2725,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) return CURLE_SSL_CONNECT_ERROR; } - SSL_CTX_set_options(backend->ctx, ctx_options); + SSL_CTX_set_options(backend->ctx, ctx_options); #ifdef HAS_NPN if(conn->bits.tls_enable_npn) - SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, conn); + SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, conn); #endif #ifdef HAS_ALPN @@ -2738,11 +2738,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) unsigned char protocols[128]; #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 -#ifndef CURL_DISABLE_PROXY - && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) -#endif - ) { + if(data->set.httpversion >= CURL_HTTP_VERSION_2 +#ifndef CURL_DISABLE_PROXY + && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) +#endif + ) { protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, @@ -2760,47 +2760,47 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* expects length prefixed preference ordered list of protocols in wire * format */ - SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur); + SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur); } #endif - if(ssl_cert || ssl_cert_blob || ssl_cert_type) { - BIO *ssl_cert_bio = NULL; - BIO *ssl_key_bio = NULL; - if(ssl_cert_blob) { - /* the typecast of blob->len is fine since it is guaranteed to never be - larger than CURL_MAX_INPUT_LENGTH */ - ssl_cert_bio = BIO_new_mem_buf(ssl_cert_blob->data, - (int)ssl_cert_blob->len); - if(!ssl_cert_bio) - result = CURLE_OUT_OF_MEMORY; - } - if(!result && SSL_SET_OPTION(key_blob)) { - ssl_key_bio = BIO_new_mem_buf(SSL_SET_OPTION(key_blob)->data, - (int)SSL_SET_OPTION(key_blob)->len); - if(!ssl_key_bio) - result = CURLE_OUT_OF_MEMORY; - } - if(!result && - !cert_stuff(conn, backend->ctx, - ssl_cert, ssl_cert_bio, ssl_cert_type, - SSL_SET_OPTION(key), ssl_key_bio, - SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd))) - result = CURLE_SSL_CERTPROBLEM; - if(ssl_cert_bio) - BIO_free(ssl_cert_bio); - if(ssl_key_bio) - BIO_free(ssl_key_bio); - if(result) + if(ssl_cert || ssl_cert_blob || ssl_cert_type) { + BIO *ssl_cert_bio = NULL; + BIO *ssl_key_bio = NULL; + if(ssl_cert_blob) { + /* the typecast of blob->len is fine since it is guaranteed to never be + larger than CURL_MAX_INPUT_LENGTH */ + ssl_cert_bio = BIO_new_mem_buf(ssl_cert_blob->data, + (int)ssl_cert_blob->len); + if(!ssl_cert_bio) + result = CURLE_OUT_OF_MEMORY; + } + if(!result && SSL_SET_OPTION(key_blob)) { + ssl_key_bio = BIO_new_mem_buf(SSL_SET_OPTION(key_blob)->data, + (int)SSL_SET_OPTION(key_blob)->len); + if(!ssl_key_bio) + result = CURLE_OUT_OF_MEMORY; + } + if(!result && + !cert_stuff(conn, backend->ctx, + ssl_cert, ssl_cert_bio, ssl_cert_type, + SSL_SET_OPTION(key), ssl_key_bio, + SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd))) + result = CURLE_SSL_CERTPROBLEM; + if(ssl_cert_bio) + BIO_free(ssl_cert_bio); + if(ssl_key_bio) + BIO_free(ssl_key_bio); + if(result) /* failf() is already done in cert_stuff() */ - return result; + return result; } ciphers = SSL_CONN_CONFIG(cipher_list); if(!ciphers) ciphers = (char *)DEFAULT_CIPHER_SELECTION; if(ciphers) { - 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; } @@ -2811,7 +2811,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) { char *ciphers13 = SSL_CONN_CONFIG(cipher_list13); if(ciphers13) { - if(!SSL_CTX_set_ciphersuites(backend->ctx, ciphers13)) { + if(!SSL_CTX_set_ciphersuites(backend->ctx, ciphers13)) { failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13); return CURLE_SSL_CIPHER; } @@ -2822,39 +2822,39 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) #ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ - SSL_CTX_set_post_handshake_auth(backend->ctx, 1); -#endif - -#ifdef HAVE_SSL_CTX_SET_EC_CURVES - { - char *curves = SSL_CONN_CONFIG(curves); - if(curves) { - if(!SSL_CTX_set1_curves_list(backend->ctx, curves)) { - failf(data, "failed setting curves list: '%s'", curves); - return CURLE_SSL_CIPHER; - } - } - } -#endif - -#ifdef USE_OPENSSL_SRP + SSL_CTX_set_post_handshake_auth(backend->ctx, 1); +#endif + +#ifdef HAVE_SSL_CTX_SET_EC_CURVES + { + char *curves = SSL_CONN_CONFIG(curves); + if(curves) { + if(!SSL_CTX_set1_curves_list(backend->ctx, curves)) { + failf(data, "failed setting curves list: '%s'", curves); + return CURLE_SSL_CIPHER; + } + } + } +#endif + +#ifdef USE_OPENSSL_SRP if(ssl_authtype == CURL_TLSAUTH_SRP) { char * const ssl_username = SSL_SET_OPTION(username); infof(data, "Using TLS-SRP username: %s\n", ssl_username); - if(!SSL_CTX_set_srp_username(backend->ctx, ssl_username)) { + if(!SSL_CTX_set_srp_username(backend->ctx, ssl_username)) { failf(data, "Unable to set SRP user name"); return CURLE_BAD_FUNCTION_ARGUMENT; } - if(!SSL_CTX_set_srp_password(backend->ctx, SSL_SET_OPTION(password))) { + if(!SSL_CTX_set_srp_password(backend->ctx, SSL_SET_OPTION(password))) { failf(data, "failed setting SRP password"); return CURLE_BAD_FUNCTION_ARGUMENT; } if(!SSL_CONN_CONFIG(cipher_list)) { infof(data, "Setting cipher list SRP\n"); - if(!SSL_CTX_set_cipher_list(backend->ctx, "SRP")) { + if(!SSL_CTX_set_cipher_list(backend->ctx, "SRP")) { failf(data, "failed setting SRP cipher list"); return CURLE_SSL_CIPHER; } @@ -2862,195 +2862,195 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) } #endif - -#if defined(USE_WIN32_CRYPTO) - /* Import certificates from the Windows root certificate store if requested. - https://stackoverflow.com/questions/9507184/ - https://github.com/d3x0r/SACK/blob/master/src/netlib/ssl_layer.c#L1037 - https://tools.ietf.org/html/rfc5280 */ - if((SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost)) && - (SSL_SET_OPTION(native_ca_store))) { - X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx); - HCERTSTORE hStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL, - TEXT("ROOT")); - - if(hStore) { - PCCERT_CONTEXT pContext = NULL; - /* The array of enhanced key usage OIDs will vary per certificate and is - declared outside of the loop so that rather than malloc/free each - iteration we can grow it with realloc, when necessary. */ - CERT_ENHKEY_USAGE *enhkey_usage = NULL; - DWORD enhkey_usage_size = 0; - - /* This loop makes a best effort to import all valid certificates from - the MS root store. If a certificate cannot be imported it is skipped. - 'result' is used to store only hard-fail conditions (such as out of - memory) that cause an early break. */ - result = CURLE_OK; - for(;;) { - X509 *x509; - FILETIME now; - BYTE key_usage[2]; - DWORD req_size; - const unsigned char *encoded_cert; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - char cert_name[256]; -#endif - - pContext = CertEnumCertificatesInStore(hStore, pContext); - if(!pContext) - break; - -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - if(!CertGetNameStringA(pContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, - NULL, cert_name, sizeof(cert_name))) { - strcpy(cert_name, "Unknown"); - } - infof(data, "SSL: Checking cert \"%s\"\n", cert_name); -#endif - - encoded_cert = (const unsigned char *)pContext->pbCertEncoded; - if(!encoded_cert) - continue; - - GetSystemTimeAsFileTime(&now); - if(CompareFileTime(&pContext->pCertInfo->NotBefore, &now) > 0 || - CompareFileTime(&now, &pContext->pCertInfo->NotAfter) > 0) - continue; - - /* If key usage exists check for signing attribute */ - if(CertGetIntendedKeyUsage(pContext->dwCertEncodingType, - pContext->pCertInfo, - key_usage, sizeof(key_usage))) { - if(!(key_usage[0] & CERT_KEY_CERT_SIGN_KEY_USAGE)) - continue; - } - else if(GetLastError()) - continue; - - /* If enhanced key usage exists check for server auth attribute. - * - * Note "In a Microsoft environment, a certificate might also have EKU - * extended properties that specify valid uses for the certificate." - * The call below checks both, and behavior varies depending on what is - * found. For more details see CertGetEnhancedKeyUsage doc. - */ - if(CertGetEnhancedKeyUsage(pContext, 0, NULL, &req_size)) { - if(req_size && req_size > enhkey_usage_size) { - void *tmp = realloc(enhkey_usage, req_size); - - if(!tmp) { - failf(data, "SSL: Out of memory allocating for OID list"); - result = CURLE_OUT_OF_MEMORY; - break; - } - - enhkey_usage = (CERT_ENHKEY_USAGE *)tmp; - enhkey_usage_size = req_size; - } - - if(CertGetEnhancedKeyUsage(pContext, 0, enhkey_usage, &req_size)) { - if(!enhkey_usage->cUsageIdentifier) { - /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate is - good for all uses. If it returns zero, the certificate has no - valid uses." */ - if((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND) - continue; - } - else { - DWORD i; - bool found = false; - - for(i = 0; i < enhkey_usage->cUsageIdentifier; ++i) { - if(!strcmp("1.3.6.1.5.5.7.3.1" /* OID server auth */, - enhkey_usage->rgpszUsageIdentifier[i])) { - found = true; - break; - } - } - - if(!found) - continue; - } - } - else - continue; - } - else - continue; - - x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded); - if(!x509) - continue; - - /* Try to import the certificate. This may fail for legitimate reasons - such as duplicate certificate, which is allowed by MS but not - OpenSSL. */ - if(X509_STORE_add_cert(store, x509) == 1) { -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - infof(data, "SSL: Imported cert \"%s\"\n", cert_name); -#endif - imported_native_ca = true; - } - X509_free(x509); - } - - free(enhkey_usage); - CertFreeCertificateContext(pContext); - CertCloseStore(hStore, 0); - - if(result) - return result; - } - if(imported_native_ca) - infof(data, "successfully imported windows ca store\n"); - else - infof(data, "error importing windows ca store, continuing anyway\n"); - } -#endif - -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) - /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */ - { - if(ssl_cafile) { - if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) { - if(verifypeer && !imported_native_ca) { - /* Fail if we insist on successfully verifying the server. */ - failf(data, "error setting certificate file: %s", ssl_cafile); - return CURLE_SSL_CACERT_BADFILE; - } - /* Continue with a warning if no certificate verif is required. */ - infof(data, "error setting certificate file, continuing anyway\n"); - } - infof(data, " CAfile: %s\n", ssl_cafile); - } - if(ssl_capath) { - if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) { - if(verifypeer && !imported_native_ca) { - /* Fail if we insist on successfully verifying the server. */ - failf(data, "error setting certificate path: %s", ssl_capath); - return CURLE_SSL_CACERT_BADFILE; - } - /* Continue with a warning if no certificate verif is required. */ - infof(data, "error setting certificate path, continuing anyway\n"); - } - infof(data, " CApath: %s\n", ssl_capath); - } - } -#else + +#if defined(USE_WIN32_CRYPTO) + /* Import certificates from the Windows root certificate store if requested. + https://stackoverflow.com/questions/9507184/ + https://github.com/d3x0r/SACK/blob/master/src/netlib/ssl_layer.c#L1037 + https://tools.ietf.org/html/rfc5280 */ + if((SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost)) && + (SSL_SET_OPTION(native_ca_store))) { + X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx); + HCERTSTORE hStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL, + TEXT("ROOT")); + + if(hStore) { + PCCERT_CONTEXT pContext = NULL; + /* The array of enhanced key usage OIDs will vary per certificate and is + declared outside of the loop so that rather than malloc/free each + iteration we can grow it with realloc, when necessary. */ + CERT_ENHKEY_USAGE *enhkey_usage = NULL; + DWORD enhkey_usage_size = 0; + + /* This loop makes a best effort to import all valid certificates from + the MS root store. If a certificate cannot be imported it is skipped. + 'result' is used to store only hard-fail conditions (such as out of + memory) that cause an early break. */ + result = CURLE_OK; + for(;;) { + X509 *x509; + FILETIME now; + BYTE key_usage[2]; + DWORD req_size; + const unsigned char *encoded_cert; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + char cert_name[256]; +#endif + + pContext = CertEnumCertificatesInStore(hStore, pContext); + if(!pContext) + break; + +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + if(!CertGetNameStringA(pContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, + NULL, cert_name, sizeof(cert_name))) { + strcpy(cert_name, "Unknown"); + } + infof(data, "SSL: Checking cert \"%s\"\n", cert_name); +#endif + + encoded_cert = (const unsigned char *)pContext->pbCertEncoded; + if(!encoded_cert) + continue; + + GetSystemTimeAsFileTime(&now); + if(CompareFileTime(&pContext->pCertInfo->NotBefore, &now) > 0 || + CompareFileTime(&now, &pContext->pCertInfo->NotAfter) > 0) + continue; + + /* If key usage exists check for signing attribute */ + if(CertGetIntendedKeyUsage(pContext->dwCertEncodingType, + pContext->pCertInfo, + key_usage, sizeof(key_usage))) { + if(!(key_usage[0] & CERT_KEY_CERT_SIGN_KEY_USAGE)) + continue; + } + else if(GetLastError()) + continue; + + /* If enhanced key usage exists check for server auth attribute. + * + * Note "In a Microsoft environment, a certificate might also have EKU + * extended properties that specify valid uses for the certificate." + * The call below checks both, and behavior varies depending on what is + * found. For more details see CertGetEnhancedKeyUsage doc. + */ + if(CertGetEnhancedKeyUsage(pContext, 0, NULL, &req_size)) { + if(req_size && req_size > enhkey_usage_size) { + void *tmp = realloc(enhkey_usage, req_size); + + if(!tmp) { + failf(data, "SSL: Out of memory allocating for OID list"); + result = CURLE_OUT_OF_MEMORY; + break; + } + + enhkey_usage = (CERT_ENHKEY_USAGE *)tmp; + enhkey_usage_size = req_size; + } + + if(CertGetEnhancedKeyUsage(pContext, 0, enhkey_usage, &req_size)) { + if(!enhkey_usage->cUsageIdentifier) { + /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate is + good for all uses. If it returns zero, the certificate has no + valid uses." */ + if((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND) + continue; + } + else { + DWORD i; + bool found = false; + + for(i = 0; i < enhkey_usage->cUsageIdentifier; ++i) { + if(!strcmp("1.3.6.1.5.5.7.3.1" /* OID server auth */, + enhkey_usage->rgpszUsageIdentifier[i])) { + found = true; + break; + } + } + + if(!found) + continue; + } + } + else + continue; + } + else + continue; + + x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded); + if(!x509) + continue; + + /* Try to import the certificate. This may fail for legitimate reasons + such as duplicate certificate, which is allowed by MS but not + OpenSSL. */ + if(X509_STORE_add_cert(store, x509) == 1) { +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + infof(data, "SSL: Imported cert \"%s\"\n", cert_name); +#endif + imported_native_ca = true; + } + X509_free(x509); + } + + free(enhkey_usage); + CertFreeCertificateContext(pContext); + CertCloseStore(hStore, 0); + + if(result) + return result; + } + if(imported_native_ca) + infof(data, "successfully imported windows ca store\n"); + else + infof(data, "error importing windows ca store, continuing anyway\n"); + } +#endif + +#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) + /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */ + { + if(ssl_cafile) { + if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) { + if(verifypeer && !imported_native_ca) { + /* Fail if we insist on successfully verifying the server. */ + failf(data, "error setting certificate file: %s", ssl_cafile); + return CURLE_SSL_CACERT_BADFILE; + } + /* Continue with a warning if no certificate verif is required. */ + infof(data, "error setting certificate file, continuing anyway\n"); + } + infof(data, " CAfile: %s\n", ssl_cafile); + } + if(ssl_capath) { + if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) { + if(verifypeer && !imported_native_ca) { + /* Fail if we insist on successfully verifying the server. */ + failf(data, "error setting certificate path: %s", ssl_capath); + return CURLE_SSL_CACERT_BADFILE; + } + /* Continue with a warning if no certificate verif is required. */ + infof(data, "error setting certificate path, continuing anyway\n"); + } + infof(data, " CApath: %s\n", ssl_capath); + } + } +#else if(ssl_cafile || ssl_capath) { /* tell SSL where to find CA certificates that are used to verify the servers certificate. */ - if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) { - if(verifypeer && !imported_native_ca) { + if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) { + if(verifypeer && !imported_native_ca) { /* Fail if we insist on successfully verifying the server. */ - failf(data, "error setting certificate verify locations:" - " CAfile: %s CApath: %s", + failf(data, "error setting certificate verify locations:" + " CAfile: %s CApath: %s", ssl_cafile ? ssl_cafile : "none", ssl_capath ? ssl_capath : "none"); return CURLE_SSL_CACERT_BADFILE; } - /* Just continue with a warning if no strict certificate verification + /* Just continue with a warning if no strict certificate verification is required. */ infof(data, "error setting certificate verify locations," " continuing anyway:\n"); @@ -3059,23 +3059,23 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* Everything is fine. */ infof(data, "successfully set certificate verify locations:\n"); } - infof(data, " CAfile: %s\n", ssl_cafile ? ssl_cafile : "none"); - infof(data, " CApath: %s\n", ssl_capath ? ssl_capath : "none"); + infof(data, " CAfile: %s\n", ssl_cafile ? ssl_cafile : "none"); + infof(data, " CApath: %s\n", ssl_capath ? ssl_capath : "none"); } -#endif - +#endif + #ifdef CURL_CA_FALLBACK - if(verifypeer && !ssl_cafile && !ssl_capath && !imported_native_ca) { + if(verifypeer && !ssl_cafile && !ssl_capath && !imported_native_ca) { /* verifying the peer without any CA certificates won't work so use openssl's built in default as fallback */ - SSL_CTX_set_default_verify_paths(backend->ctx); + SSL_CTX_set_default_verify_paths(backend->ctx); } #endif if(ssl_crlfile) { /* tell SSL where to find CRL file that is used to check certificate * revocation */ - lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(backend->ctx), + lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(backend->ctx), X509_LOOKUP_file()); if(!lookup || (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) { @@ -3084,50 +3084,50 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) } /* Everything is fine. */ infof(data, "successfully load CRL file:\n"); - X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), + X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); infof(data, " CRLfile: %s\n", ssl_crlfile); } if(verifypeer) { - /* Try building a chain using issuers in the trusted store first to avoid - problems with server-sent legacy intermediates. Newer versions of - OpenSSL do alternate chain checking by default but we do not know how to - determine that in a reliable manner. - https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest - */ -#if defined(X509_V_FLAG_TRUSTED_FIRST) - X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), + /* Try building a chain using issuers in the trusted store first to avoid + problems with server-sent legacy intermediates. Newer versions of + OpenSSL do alternate chain checking by default but we do not know how to + determine that in a reliable manner. + https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest + */ +#if defined(X509_V_FLAG_TRUSTED_FIRST) + X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), X509_V_FLAG_TRUSTED_FIRST); #endif -#ifdef X509_V_FLAG_PARTIAL_CHAIN - if(!SSL_SET_OPTION(no_partialchain) && !ssl_crlfile) { - /* Have intermediate certificates in the trust store be treated as - trust-anchors, in the same way as self-signed root CA certificates - are. This allows users to verify servers using the intermediate cert - only, instead of needing the whole chain. - - Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we - cannot do partial chains with CRL check. - */ - X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), - X509_V_FLAG_PARTIAL_CHAIN); - } -#endif - } - +#ifdef X509_V_FLAG_PARTIAL_CHAIN + if(!SSL_SET_OPTION(no_partialchain) && !ssl_crlfile) { + /* Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert + only, instead of needing the whole chain. + + Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we + cannot do partial chains with CRL check. + */ + X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), + X509_V_FLAG_PARTIAL_CHAIN); + } +#endif + } + /* SSL always tries to verify the peer, this only says whether it should * fail to connect if the verification fails, or if it should continue * anyway. In the latter case the result of the verification is checked with * SSL_get_verify_result() below. */ - SSL_CTX_set_verify(backend->ctx, + SSL_CTX_set_verify(backend->ctx, verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ -#ifdef HAVE_KEYLOG_CALLBACK - if(Curl_tls_keylog_enabled()) { - SSL_CTX_set_keylog_callback(backend->ctx, ossl_keylog_callback); +#ifdef HAVE_KEYLOG_CALLBACK + if(Curl_tls_keylog_enabled()) { + SSL_CTX_set_keylog_callback(backend->ctx, ossl_keylog_callback); } #endif @@ -3135,16 +3135,16 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) * callback. Use the "external storage" mode to avoid that OpenSSL creates * an internal session cache. */ - SSL_CTX_set_session_cache_mode(backend->ctx, + SSL_CTX_set_session_cache_mode(backend->ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); - SSL_CTX_sess_set_new_cb(backend->ctx, ossl_new_session_cb); + SSL_CTX_sess_set_new_cb(backend->ctx, ossl_new_session_cb); /* give application a chance to interfere with SSL set up. */ if(data->set.ssl.fsslctx) { - Curl_set_in_callback(data, true); - result = (*data->set.ssl.fsslctx)(data, backend->ctx, + Curl_set_in_callback(data, true); + result = (*data->set.ssl.fsslctx)(data, backend->ctx, data->set.ssl.fsslctxp); - Curl_set_in_callback(data, false); + Curl_set_in_callback(data, false); if(result) { failf(data, "error signaled by ssl ctx callback"); return result; @@ -3152,10 +3152,10 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) } /* Lets make an SSL structure */ - 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; } @@ -3163,23 +3163,23 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ !defined(OPENSSL_NO_OCSP) if(SSL_CONN_CONFIG(verifystatus)) - SSL_set_tlsext_status_type(backend->handle, TLSEXT_STATUSTYPE_ocsp); + SSL_set_tlsext_status_type(backend->handle, TLSEXT_STATUSTYPE_ocsp); #endif #if defined(OPENSSL_IS_BORINGSSL) && defined(ALLOW_RENEG) - SSL_set_renegotiate_mode(backend->handle, ssl_renegotiate_freely); + SSL_set_renegotiate_mode(backend->handle, ssl_renegotiate_freely); #endif - SSL_set_connect_state(backend->handle); + SSL_set_connect_state(backend->handle); - backend->server_cert = 0x0; + backend->server_cert = 0x0; #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) && #ifdef ENABLE_IPV6 (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && #endif sni && - !SSL_set_tlsext_host_name(backend->handle, hostname)) + !SSL_set_tlsext_host_name(backend->handle, hostname)) infof(data, "WARNING: failed to configure server name indication (SNI) " "TLS extension\n"); #endif @@ -3193,14 +3193,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) if(connectdata_idx >= 0 && sockindex_idx >= 0) { /* Store the data needed for the "new session" callback. * The sockindex is stored as a pointer to an array element. */ - SSL_set_ex_data(backend->handle, connectdata_idx, conn); - SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); + SSL_set_ex_data(backend->handle, connectdata_idx, conn); + SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); } Curl_ssl_sessionid_lock(conn); if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { /* we got a session id, use it! */ - if(!SSL_set_session(backend->handle, ssl_sessionid)) { + if(!SSL_set_session(backend->handle, ssl_sessionid)) { Curl_ssl_sessionid_unlock(conn); failf(data, "SSL: SSL_set_session failed: %s", ossl_strerror(ERR_get_error(), error_buffer, @@ -3213,7 +3213,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) Curl_ssl_sessionid_unlock(conn); } -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY if(conn->proxy_ssl[sockindex].use) { BIO *const bio = BIO_new(BIO_f_ssl()); SSL *handle = conn->proxy_ssl[sockindex].backend->handle; @@ -3221,11 +3221,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) DEBUGASSERT(handle != NULL); DEBUGASSERT(bio != NULL); BIO_set_ssl(bio, handle, FALSE); - SSL_set_bio(backend->handle, bio, bio); + SSL_set_bio(backend->handle, bio, bio); } - else -#endif - if(!SSL_set_fd(backend->handle, (int)sockfd)) { + else +#endif + if(!SSL_set_fd(backend->handle, (int)sockfd)) { /* pass the raw socket into the SSL layers */ failf(data, "SSL: SSL_set_fd failed: %s", ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer))); @@ -3242,28 +3242,28 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) struct Curl_easy *data = conn->data; int err; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; DEBUGASSERT(ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state || ssl_connect_2_writing == connssl->connecting_state); ERR_clear_error(); - err = SSL_connect(backend->handle); -#ifndef HAVE_KEYLOG_CALLBACK - if(Curl_tls_keylog_enabled()) { - /* If key logging is enabled, wait for the handshake to complete and then - * proceed with logging secrets (for TLS 1.2 or older). - */ - ossl_log_tls12_secret(backend->handle, &backend->keylog_done); - } + err = SSL_connect(backend->handle); +#ifndef HAVE_KEYLOG_CALLBACK + if(Curl_tls_keylog_enabled()) { + /* If key logging is enabled, wait for the handshake to complete and then + * proceed with logging secrets (for TLS 1.2 or older). + */ + ossl_log_tls12_secret(backend->handle, &backend->keylog_done); + } #endif /* 1 is fine 0 is "not successful but was shut down controlled" <0 is "handshake was not successful, because a fatal error occurred" */ if(1 != err) { - int detail = SSL_get_error(backend->handle, err); + int detail = SSL_get_error(backend->handle, err); if(SSL_ERROR_WANT_READ == detail) { connssl->connecting_state = ssl_connect_2_reading; @@ -3300,13 +3300,13 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) reason = ERR_GET_REASON(errdetail); if((lib == ERR_LIB_SSL) && - ((reason == SSL_R_CERTIFICATE_VERIFY_FAILED) || - (reason == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED))) { + ((reason == SSL_R_CERTIFICATE_VERIFY_FAILED) || + (reason == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED))) { result = CURLE_PEER_FAILED_VERIFICATION; - lerr = SSL_get_verify_result(backend->handle); + lerr = SSL_get_verify_result(backend->handle); if(lerr != X509_V_OK) { - SSL_SET_OPTION_LVALUE(certverifyresult) = lerr; + SSL_SET_OPTION_LVALUE(certverifyresult) = lerr; msnprintf(error_buffer, sizeof(error_buffer), "SSL certificate problem: %s", X509_verify_cert_error_string(lerr)); @@ -3328,19 +3328,19 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) * the SO_ERROR is also lost. */ if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) { - const char * const hostname = SSL_HOST_NAME(); -#ifndef CURL_DISABLE_PROXY + const char * const hostname = SSL_HOST_NAME(); +#ifndef CURL_DISABLE_PROXY const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const long int port = conn->remote_port; -#endif - char extramsg[80]=""; - int sockerr = SOCKERRNO; - if(sockerr && detail == SSL_ERROR_SYSCALL) - Curl_strerror(sockerr, extramsg, sizeof(extramsg)); +#else + const long int port = conn->remote_port; +#endif + char extramsg[80]=""; + int sockerr = SOCKERRNO; + if(sockerr && detail == SSL_ERROR_SYSCALL) + Curl_strerror(sockerr, extramsg, sizeof(extramsg)); failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ", - extramsg[0] ? extramsg : SSL_ERROR_to_str(detail), - hostname, port); + extramsg[0] ? extramsg : SSL_ERROR_to_str(detail), + hostname, port); return result; } @@ -3356,8 +3356,8 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) /* Informational message */ infof(data, "SSL connection using %s / %s\n", - get_ssl_version_txt(backend->handle), - SSL_get_cipher(backend->handle)); + get_ssl_version_txt(backend->handle), + SSL_get_cipher(backend->handle)); #ifdef HAS_ALPN /* Sets data and len to negotiated protocol, len is 0 if no protocol was @@ -3366,7 +3366,7 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) if(conn->bits.tls_enable_alpn) { const unsigned char *neg_protocol; unsigned int len; - SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len); + SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len); if(len != 0) { infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol); @@ -3416,7 +3416,7 @@ do { \ Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \ if(1 != BIO_reset(mem)) \ break; \ -} while(0) +} while(0) static void pubkey_show(struct Curl_easy *data, BIO *mem, @@ -3448,10 +3448,10 @@ do { \ if(_type->_name) { \ pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \ } \ -} while(0) +} while(0) #endif -static void X509V3_ext(struct Curl_easy *data, +static void X509V3_ext(struct Curl_easy *data, int certnum, CONST_EXTS STACK_OF(X509_EXTENSION) *exts) { @@ -3459,7 +3459,7 @@ static void X509V3_ext(struct Curl_easy *data, if((int)sk_X509_EXTENSION_num(exts) <= 0) /* no extensions, bail out */ - return; + return; for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) { ASN1_OBJECT *obj; @@ -3469,7 +3469,7 @@ static void X509V3_ext(struct Curl_easy *data, BIO *bio_out = BIO_new(BIO_s_mem()); if(!bio_out) - return; + return; obj = X509_EXTENSION_get_object(ext); @@ -3479,8 +3479,8 @@ static void X509V3_ext(struct Curl_easy *data, ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); BIO_get_mem_ptr(bio_out, &biomem); - Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data, - biomem->length); + Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data, + biomem->length); BIO_free(bio_out); } } @@ -3500,9 +3500,9 @@ static CURLcode get_cert_chain(struct connectdata *conn, struct Curl_easy *data = conn->data; numcert_t numcerts; BIO *mem; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; - sk = SSL_get_peer_cert_chain(backend->handle); + sk = SSL_get_peer_cert_chain(backend->handle); if(!sk) { return CURLE_OUT_OF_MEMORY; } @@ -3786,14 +3786,14 @@ static CURLcode servercert(struct connectdata *conn, char buffer[2048]; const char *ptr; BIO *mem = BIO_new(BIO_s_mem()); - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; if(data->set.ssl.certinfo) /* we've been asked to gather certificate info! */ (void)get_cert_chain(conn, connssl); - backend->server_cert = SSL_get_peer_certificate(backend->handle); - if(!backend->server_cert) { + backend->server_cert = SSL_get_peer_certificate(backend->handle); + if(!backend->server_cert) { BIO_free(mem); if(!strict) return CURLE_OK; @@ -3804,19 +3804,19 @@ static CURLcode servercert(struct connectdata *conn, infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server"); - rc = x509_name_oneline(X509_get_subject_name(backend->server_cert), + rc = x509_name_oneline(X509_get_subject_name(backend->server_cert), buffer, sizeof(buffer)); infof(data, " subject: %s\n", rc?"[NONE]":buffer); #ifndef CURL_DISABLE_VERBOSE_STRINGS { long len; - ASN1_TIME_print(mem, X509_get0_notBefore(backend->server_cert)); + ASN1_TIME_print(mem, X509_get0_notBefore(backend->server_cert)); len = BIO_get_mem_data(mem, (char **) &ptr); infof(data, " start date: %.*s\n", len, ptr); (void)BIO_reset(mem); - ASN1_TIME_print(mem, X509_get0_notAfter(backend->server_cert)); + ASN1_TIME_print(mem, X509_get0_notAfter(backend->server_cert)); len = BIO_get_mem_data(mem, (char **) &ptr); infof(data, " expire date: %.*s\n", len, ptr); (void)BIO_reset(mem); @@ -3826,15 +3826,15 @@ static CURLcode servercert(struct connectdata *conn, BIO_free(mem); if(SSL_CONN_CONFIG(verifyhost)) { - result = verifyhost(conn, backend->server_cert); + result = verifyhost(conn, backend->server_cert); if(result) { - X509_free(backend->server_cert); - backend->server_cert = NULL; + X509_free(backend->server_cert); + backend->server_cert = NULL; return result; } } - rc = x509_name_oneline(X509_get_issuer_name(backend->server_cert), + rc = x509_name_oneline(X509_get_issuer_name(backend->server_cert), buffer, sizeof(buffer)); if(rc) { if(strict) @@ -3848,32 +3848,32 @@ static CURLcode servercert(struct connectdata *conn, deallocating the certificate. */ /* e.g. match issuer name with provided issuer certificate */ - if(SSL_SET_OPTION(issuercert) || SSL_SET_OPTION(issuercert_blob)) { - if(SSL_SET_OPTION(issuercert_blob)) - fp = BIO_new_mem_buf(SSL_SET_OPTION(issuercert_blob)->data, - (int)SSL_SET_OPTION(issuercert_blob)->len); - else { - fp = BIO_new(BIO_s_file()); - if(fp == NULL) { - failf(data, - "BIO_new return NULL, " OSSL_PACKAGE - " error %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer)) ); - X509_free(backend->server_cert); - backend->server_cert = NULL; - return CURLE_OUT_OF_MEMORY; - } - - if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { - if(strict) - failf(data, "SSL: Unable to open issuer cert (%s)", - SSL_SET_OPTION(issuercert)); - BIO_free(fp); - X509_free(backend->server_cert); - backend->server_cert = NULL; - return CURLE_SSL_ISSUER_ERROR; - } + if(SSL_SET_OPTION(issuercert) || SSL_SET_OPTION(issuercert_blob)) { + if(SSL_SET_OPTION(issuercert_blob)) + fp = BIO_new_mem_buf(SSL_SET_OPTION(issuercert_blob)->data, + (int)SSL_SET_OPTION(issuercert_blob)->len); + else { + fp = BIO_new(BIO_s_file()); + if(fp == NULL) { + failf(data, + "BIO_new return NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + X509_free(backend->server_cert); + backend->server_cert = NULL; + return CURLE_OUT_OF_MEMORY; + } + + if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { + if(strict) + failf(data, "SSL: Unable to open issuer cert (%s)", + SSL_SET_OPTION(issuercert)); + BIO_free(fp); + X509_free(backend->server_cert); + backend->server_cert = NULL; + return CURLE_SSL_ISSUER_ERROR; + } } issuer = PEM_read_bio_X509(fp, NULL, ZERO_NULL, NULL); @@ -3883,19 +3883,19 @@ static CURLcode servercert(struct connectdata *conn, SSL_SET_OPTION(issuercert)); BIO_free(fp); X509_free(issuer); - X509_free(backend->server_cert); - backend->server_cert = NULL; + X509_free(backend->server_cert); + backend->server_cert = NULL; return CURLE_SSL_ISSUER_ERROR; } - if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) { + if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) { if(strict) failf(data, "SSL: Certificate issuer check failed (%s)", SSL_SET_OPTION(issuercert)); BIO_free(fp); X509_free(issuer); - X509_free(backend->server_cert); - backend->server_cert = NULL; + X509_free(backend->server_cert); + backend->server_cert = NULL; return CURLE_SSL_ISSUER_ERROR; } @@ -3905,9 +3905,9 @@ static CURLcode servercert(struct connectdata *conn, X509_free(issuer); } - lerr = SSL_get_verify_result(backend->handle); - SSL_SET_OPTION_LVALUE(certverifyresult) = lerr; - if(lerr != X509_V_OK) { + lerr = SSL_get_verify_result(backend->handle); + SSL_SET_OPTION_LVALUE(certverifyresult) = lerr; + if(lerr != X509_V_OK) { if(SSL_CONN_CONFIG(verifypeer)) { /* We probably never reach this, because SSL_connect() will fail and we return earlier if verifypeer is set? */ @@ -3930,8 +3930,8 @@ static CURLcode servercert(struct connectdata *conn, if(SSL_CONN_CONFIG(verifystatus)) { result = verifystatus(conn, connssl); if(result) { - X509_free(backend->server_cert); - backend->server_cert = NULL; + X509_free(backend->server_cert); + backend->server_cert = NULL; return result; } } @@ -3944,13 +3944,13 @@ static CURLcode servercert(struct connectdata *conn, ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; if(!result && ptr) { - result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr); + result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr); if(result) failf(data, "SSL: public key does not match pinned public key!"); } - X509_free(backend->server_cert); - backend->server_cert = NULL; + X509_free(backend->server_cert); + backend->server_cert = NULL; connssl->connecting_state = ssl_connect_done; return result; @@ -4001,7 +4001,7 @@ static CURLcode ossl_connect_common(struct connectdata *conn, if(ssl_connect_1 == connssl->connecting_state) { /* Find out how much more time we're allowed */ - const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); if(timeout_ms < 0) { /* no need to continue if time already is up */ @@ -4019,7 +4019,7 @@ static CURLcode ossl_connect_common(struct connectdata *conn, ssl_connect_2_writing == connssl->connecting_state) { /* check allowed time left */ - const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); if(timeout_ms < 0) { /* no need to continue if time already is up */ @@ -4118,13 +4118,13 @@ static bool Curl_ossl_data_pending(const struct connectdata *conn, const struct ssl_connect_data *connssl = &conn->ssl[connindex]; if(connssl->backend->handle && SSL_pending(connssl->backend->handle)) return TRUE; -#ifndef CURL_DISABLE_PROXY - { - const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex]; - if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle)) - return TRUE; - } -#endif +#ifndef CURL_DISABLE_PROXY + { + const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex]; + if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle)) + return TRUE; + } +#endif return FALSE; } @@ -4144,15 +4144,15 @@ static ssize_t ossl_send(struct connectdata *conn, int memlen; int rc; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; ERR_clear_error(); memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; - rc = SSL_write(backend->handle, mem, memlen); + rc = SSL_write(backend->handle, mem, memlen); if(rc <= 0) { - err = SSL_get_error(backend->handle, rc); + err = SSL_get_error(backend->handle, rc); switch(err) { case SSL_ERROR_WANT_READ: @@ -4163,33 +4163,33 @@ static ssize_t ossl_send(struct connectdata *conn, *curlcode = CURLE_AGAIN; return -1; case SSL_ERROR_SYSCALL: - { - int sockerr = SOCKERRNO; - sslerror = ERR_get_error(); - if(sslerror) - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); - else if(sockerr) - Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); - else { - strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); - error_buffer[sizeof(error_buffer) - 1] = '\0'; - } - failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d", - error_buffer, sockerr); - *curlcode = CURLE_SEND_ERROR; - return -1; - } + { + int sockerr = SOCKERRNO; + sslerror = ERR_get_error(); + if(sslerror) + ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); + else if(sockerr) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); + error_buffer[sizeof(error_buffer) - 1] = '\0'; + } + failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d", + error_buffer, sockerr); + *curlcode = CURLE_SEND_ERROR; + return -1; + } case SSL_ERROR_SSL: /* A failure in the SSL library occurred, usually a protocol error. The OpenSSL error queue contains more information on the error. */ sslerror = ERR_get_error(); if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL && ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET && - conn->ssl[sockindex].state == ssl_connection_complete -#ifndef CURL_DISABLE_PROXY - && conn->proxy_ssl[sockindex].state == ssl_connection_complete -#endif - ) { + conn->ssl[sockindex].state == ssl_connection_complete +#ifndef CURL_DISABLE_PROXY + && conn->proxy_ssl[sockindex].state == ssl_connection_complete +#endif + ) { char ver[120]; Curl_ossl_version(ver, 120); failf(conn->data, "Error: %s does not support double SSL tunneling.", @@ -4222,25 +4222,25 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ ssize_t nread; int buffsize; struct ssl_connect_data *connssl = &conn->ssl[num]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; ERR_clear_error(); buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; - nread = (ssize_t)SSL_read(backend->handle, buf, buffsize); + nread = (ssize_t)SSL_read(backend->handle, buf, buffsize); if(nread <= 0) { /* failed SSL_read */ - int err = SSL_get_error(backend->handle, (int)nread); + int err = SSL_get_error(backend->handle, (int)nread); switch(err) { case SSL_ERROR_NONE: /* this is not an error */ break; case SSL_ERROR_ZERO_RETURN: /* no more data */ /* close_notify alert */ - if(num == FIRSTSOCKET) - /* mark the connection for close if it is indeed the control - connection */ - connclose(conn, "TLS close_notify"); + if(num == FIRSTSOCKET) + /* mark the connection for close if it is indeed the control + connection */ + connclose(conn, "TLS close_notify"); break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: @@ -4255,44 +4255,44 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ if((nread < 0) || sslerror) { /* If the return code was negative or there actually is an error in the queue */ - int sockerr = SOCKERRNO; - if(sslerror) - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); - else if(sockerr && err == SSL_ERROR_SYSCALL) - Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); - else { - strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); - error_buffer[sizeof(error_buffer) - 1] = '\0'; - } + int sockerr = SOCKERRNO; + if(sslerror) + ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); + else if(sockerr && err == SSL_ERROR_SYSCALL) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); + error_buffer[sizeof(error_buffer) - 1] = '\0'; + } failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d", - error_buffer, sockerr); + error_buffer, sockerr); *curlcode = CURLE_RECV_ERROR; return -1; } - /* For debug builds be a little stricter and error on any - SSL_ERROR_SYSCALL. For example a server may have closed the connection - abruptly without a close_notify alert. For compatibility with older - peers we don't do this by default. #4624 - - We can use this to gauge how many users may be affected, and - if it goes ok eventually transition to allow in dev and release with - the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ -#ifdef DEBUGBUILD - if(err == SSL_ERROR_SYSCALL) { - int sockerr = SOCKERRNO; - if(sockerr) - Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); - else { - msnprintf(error_buffer, sizeof(error_buffer), - "Connection closed abruptly"); - } - failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d" - " (Fatal because this is a curl debug build)", - error_buffer, sockerr); - *curlcode = CURLE_RECV_ERROR; - return -1; - } -#endif + /* For debug builds be a little stricter and error on any + SSL_ERROR_SYSCALL. For example a server may have closed the connection + abruptly without a close_notify alert. For compatibility with older + peers we don't do this by default. #4624 + + We can use this to gauge how many users may be affected, and + if it goes ok eventually transition to allow in dev and release with + the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ +#ifdef DEBUGBUILD + if(err == SSL_ERROR_SYSCALL) { + int sockerr = SOCKERRNO; + if(sockerr) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + msnprintf(error_buffer, sizeof(error_buffer), + "Connection closed abruptly"); + } + failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d" + " (Fatal because this is a curl debug build)", + error_buffer, sockerr); + *curlcode = CURLE_RECV_ERROR; + return -1; + } +#endif } } return nread; @@ -4300,35 +4300,35 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ static size_t Curl_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 */ - char *p; - int count; - const char *ver = OpenSSL_version(OPENSSL_VERSION); - const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ - if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) { - ver += sizeof(expected) - 1; - } - count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); - for(p = buffer; *p; ++p) { - if(ISSPACE(*p)) - *p = '_'; - } - return count; -#endif -#elif defined(OPENSSL_IS_BORINGSSL) +#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 */ + char *p; + int count; + const char *ver = OpenSSL_version(OPENSSL_VERSION); + const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ + if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) { + ver += sizeof(expected) - 1; + } + count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); + for(p = buffer; *p; ++p) { + if(ISSPACE(*p)) + *p = '_'; + } + return count; +#endif +#elif defined(OPENSSL_IS_BORINGSSL) return msnprintf(buffer, size, OSSL_PACKAGE); #elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING) return msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); #else - /* not LibreSSL, BoringSSL and not using OpenSSL_version */ + /* not LibreSSL, BoringSSL and not using OpenSSL_version */ char sub[3]; unsigned long ssleay_value; @@ -4396,9 +4396,9 @@ static CURLcode Curl_ossl_md5sum(unsigned char *tmp, /* input */ (void) unused; mdctx = EVP_MD_CTX_create(); - if(!mdctx) - return CURLE_OUT_OF_MEMORY; - EVP_DigestInit(mdctx, EVP_md5()); + if(!mdctx) + return CURLE_OUT_OF_MEMORY; + EVP_DigestInit(mdctx, EVP_md5()); EVP_DigestUpdate(mdctx, tmp, tmplen); EVP_DigestFinal_ex(mdctx, md5sum, &len); EVP_MD_CTX_destroy(mdctx); @@ -4415,10 +4415,10 @@ static CURLcode Curl_ossl_sha256sum(const unsigned char *tmp, /* input */ unsigned int len = 0; (void) unused; - mdctx = EVP_MD_CTX_create(); - if(!mdctx) - return CURLE_OUT_OF_MEMORY; - EVP_DigestInit(mdctx, EVP_sha256()); + mdctx = EVP_MD_CTX_create(); + if(!mdctx) + return CURLE_OUT_OF_MEMORY; + EVP_DigestInit(mdctx, EVP_sha256()); EVP_DigestUpdate(mdctx, tmp, tmplen); EVP_DigestFinal_ex(mdctx, sha256sum, &len); EVP_MD_CTX_destroy(mdctx); @@ -4440,9 +4440,9 @@ static void *Curl_ossl_get_internals(struct ssl_connect_data *connssl, CURLINFO info) { /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; return info == CURLINFO_TLS_SESSION ? - (void *)backend->ctx : (void *)backend->handle; + (void *)backend->ctx : (void *)backend->handle; } const struct Curl_ssl Curl_ssl_openssl = { diff --git a/contrib/libs/curl/lib/vtls/openssl.h b/contrib/libs/curl/lib/vtls/openssl.h index 2f6e1b2db8..1a1b638c62 100644 --- a/contrib/libs/curl/lib/vtls/openssl.h +++ b/contrib/libs/curl/lib/vtls/openssl.h @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is diff --git a/contrib/libs/curl/lib/vtls/schannel.c b/contrib/libs/curl/lib/vtls/schannel.c index d7bc38917f..2bc1d7f839 100644 --- a/contrib/libs/curl/lib/vtls/schannel.c +++ b/contrib/libs/curl/lib/vtls/schannel.c @@ -7,11 +7,11 @@ * * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de> * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> - * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -39,20 +39,20 @@ #include "schannel.h" #include "vtls.h" -#include "strcase.h" +#include "strcase.h" #include "sendf.h" #include "connect.h" /* for the connect timeout */ #include "strerror.h" -#include "select.h" /* for the socket readiness */ +#include "select.h" /* for the socket readiness */ #include "inet_pton.h" /* for IP addr SNI check */ #include "curl_multibyte.h" #include "warnless.h" #include "x509asn1.h" #include "curl_printf.h" #include "multiif.h" -#include "version_win32.h" +#include "version_win32.h" -/* The last #include file should be: */ +/* The last #include file should be: */ #include "curl_memory.h" #include "memdebug.h" @@ -170,25 +170,25 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn) long i = ssl_version; switch(ssl_version_max) { - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_DEFAULT: - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; - break; + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_DEFAULT: + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + break; } for(; i <= (ssl_version_max >> 16); ++i) { switch(i) { - case CURL_SSLVERSION_TLSv1_0: - schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT; - break; - case CURL_SSLVERSION_TLSv1_1: - schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT; - break; - case CURL_SSLVERSION_TLSv1_2: - schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT; - break; - case CURL_SSLVERSION_TLSv1_3: - failf(data, "schannel: TLS 1.3 is not yet supported"); - return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_0: + schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT; + break; + case CURL_SSLVERSION_TLSv1_1: + schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT; + break; + case CURL_SSLVERSION_TLSv1_2: + schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT; + break; + case CURL_SSLVERSION_TLSv1_3: + failf(data, "schannel: TLS 1.3 is not yet supported"); + return CURLE_SSL_CONNECT_ERROR; } } return CURLE_OK; @@ -196,9 +196,9 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn) /*longest is 26, buffer is slightly bigger*/ #define LONGEST_ALG_ID 32 -#define CIPHEROPTION(X) \ - if(strcmp(#X, tmp) == 0) \ - return X +#define CIPHEROPTION(X) \ + if(strcmp(#X, tmp) == 0) \ + return X static int get_alg_id_by_name(char *name) @@ -274,11 +274,11 @@ get_alg_id_by_name(char *name) #ifdef CALG_HMAC CIPHEROPTION(CALG_HMAC); #endif -#if !defined(__W32API_MAJOR_VERSION) || \ - !defined(__W32API_MINOR_VERSION) || \ - defined(__MINGW64_VERSION_MAJOR) || \ - (__W32API_MAJOR_VERSION > 5) || \ - ((__W32API_MAJOR_VERSION == 5) && (__W32API_MINOR_VERSION > 0)) +#if !defined(__W32API_MAJOR_VERSION) || \ + !defined(__W32API_MINOR_VERSION) || \ + defined(__MINGW64_VERSION_MAJOR) || \ + (__W32API_MAJOR_VERSION > 5) || \ + ((__W32API_MAJOR_VERSION == 5) && (__W32API_MINOR_VERSION > 0)) /* CALG_TLS1PRF has a syntax error in MinGW's w32api up to version 5.0, see https://osdn.net/projects/mingw/ticket/38391 */ CIPHEROPTION(CALG_TLS1PRF); @@ -340,14 +340,14 @@ set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers) if(startCur) startCur++; } - schannel_cred->palgSupportedAlgs = algIds; + schannel_cred->palgSupportedAlgs = algIds; schannel_cred->cSupportedAlgs = algCount; return CURLE_OK; } #ifdef HAS_CLIENT_CERT_PATH - -/* Function allocates memory for store_path only if CURLE_OK is returned */ + +/* Function allocates memory for store_path only if CURLE_OK is returned */ static CURLcode get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, TCHAR **thumbprint) @@ -390,10 +390,10 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, if(sep == NULL) return CURLE_SSL_CERTPROBLEM; - *thumbprint = sep + 1; - if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) - return CURLE_SSL_CERTPROBLEM; - + *thumbprint = sep + 1; + if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) + return CURLE_SSL_CERTPROBLEM; + *sep = TEXT('\0'); *store_path = _tcsdup(store_path_start); *sep = TEXT('\\'); @@ -420,40 +420,40 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) SCHANNEL_CRED schannel_cred; PCCERT_CONTEXT client_certs[1] = { NULL }; SECURITY_STATUS sspi_status = SEC_E_OK; - struct Curl_schannel_cred *old_cred = NULL; + struct Curl_schannel_cred *old_cred = NULL; struct in_addr addr; #ifdef ENABLE_IPV6 struct in6_addr addr6; #endif TCHAR *host_name; CURLcode result; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; -#else - char * const hostname = conn->host.name; -#endif +#else + char * const hostname = conn->host.name; +#endif DEBUGF(infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", hostname, conn->remote_port)); - if(curlx_verify_windows_version(5, 1, 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. */ - infof(data, "schannel: Windows version is old and may not be able to " - "connect to some servers due to lack of SNI, algorithms, etc.\n"); + if(curlx_verify_windows_version(5, 1, 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. */ + infof(data, "schannel: Windows version is old and may not be able to " + "connect to some servers due to lack of SNI, algorithms, etc.\n"); } #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 && - !GetProcAddress(GetModuleHandle(TEXT("ntdll")), - "wine_get_version") && - curlx_verify_windows_version(6, 3, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL); + !GetProcAddress(GetModuleHandle(TEXT("ntdll")), + "wine_get_version") && + curlx_verify_windows_version(6, 3, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL); #else BACKEND->use_alpn = false; #endif @@ -469,8 +469,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) #else #ifdef HAS_MANUAL_VERIFY_API if(SSL_CONN_CONFIG(CAfile)) { - if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) { + if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) { BACKEND->use_manual_cred_validation = true; } else { @@ -527,15 +527,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) DEBUGF(infof(data, "schannel: disabled server certificate revocation " "checks\n")); } - else if(data->set.ssl.revoke_best_effort) { - schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN; - - DEBUGF(infof(data, "schannel: ignore revocation offline errors")); - } + else if(data->set.ssl.revoke_best_effort) { + schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | + SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN; + + DEBUGF(infof(data, "schannel: ignore revocation offline errors")); + } else { schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; - + DEBUGF(infof(data, "schannel: checking server certificate revocation\n")); } @@ -562,12 +562,12 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) case CURL_SSLVERSION_TLSv1_1: case CURL_SSLVERSION_TLSv1_2: case CURL_SSLVERSION_TLSv1_3: - { - result = set_ssl_version_min_max(&schannel_cred, conn); - if(result != CURLE_OK) - return result; - break; - } + { + result = set_ssl_version_min_max(&schannel_cred, conn); + if(result != CURLE_OK) + return result; + break; + } case CURL_SSLVERSION_SSLv3: schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; break; @@ -590,199 +590,199 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) #ifdef HAS_CLIENT_CERT_PATH /* client certificate */ - if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { - DWORD cert_store_name = 0; - TCHAR *cert_store_path = NULL; - TCHAR *cert_thumbprint_str = NULL; + if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { + DWORD cert_store_name = 0; + TCHAR *cert_store_path = NULL; + TCHAR *cert_thumbprint_str = NULL; CRYPT_HASH_BLOB cert_thumbprint; BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN]; - HCERTSTORE cert_store = NULL; - FILE *fInCert = NULL; - void *certdata = NULL; - size_t certsize = 0; - bool blob = data->set.ssl.primary.cert_blob != NULL; - TCHAR *cert_path = NULL; - if(blob) { - certdata = data->set.ssl.primary.cert_blob->data; - certsize = data->set.ssl.primary.cert_blob->len; - } - else { - cert_path = curlx_convert_UTF8_to_tchar( - data->set.ssl.primary.clientcert); - if(!cert_path) - return CURLE_OUT_OF_MEMORY; - - result = get_cert_location(cert_path, &cert_store_name, - &cert_store_path, &cert_thumbprint_str); - - if(result && (data->set.ssl.primary.clientcert[0]!='\0')) - fInCert = fopen(data->set.ssl.primary.clientcert, "rb"); - - if(result && !fInCert) { - failf(data, "schannel: Failed to get certificate location" - " or file for %s", - data->set.ssl.primary.clientcert); - curlx_unicodefree(cert_path); - return result; - } + HCERTSTORE cert_store = NULL; + FILE *fInCert = NULL; + void *certdata = NULL; + size_t certsize = 0; + bool blob = data->set.ssl.primary.cert_blob != NULL; + TCHAR *cert_path = NULL; + if(blob) { + certdata = data->set.ssl.primary.cert_blob->data; + certsize = data->set.ssl.primary.cert_blob->len; + } + else { + cert_path = curlx_convert_UTF8_to_tchar( + data->set.ssl.primary.clientcert); + if(!cert_path) + return CURLE_OUT_OF_MEMORY; + + result = get_cert_location(cert_path, &cert_store_name, + &cert_store_path, &cert_thumbprint_str); + + if(result && (data->set.ssl.primary.clientcert[0]!='\0')) + fInCert = fopen(data->set.ssl.primary.clientcert, "rb"); + + if(result && !fInCert) { + failf(data, "schannel: Failed to get certificate location" + " or file for %s", + data->set.ssl.primary.clientcert); + curlx_unicodefree(cert_path); + return result; + } } - if((fInCert || blob) && (data->set.ssl.cert_type) && - (!strcasecompare(data->set.ssl.cert_type, "P12"))) { - failf(data, "schannel: certificate format compatibility error " - " for %s", - blob ? "(memory blob)" : data->set.ssl.primary.clientcert); - curlx_unicodefree(cert_path); + if((fInCert || blob) && (data->set.ssl.cert_type) && + (!strcasecompare(data->set.ssl.cert_type, "P12"))) { + failf(data, "schannel: certificate format compatibility error " + " for %s", + blob ? "(memory blob)" : data->set.ssl.primary.clientcert); + curlx_unicodefree(cert_path); return CURLE_SSL_CERTPROBLEM; } - if(fInCert || blob) { - /* Reading a .P12 or .pfx file, like the example at bottom of - https://social.msdn.microsoft.com/Forums/windowsdesktop/ - en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5 - */ - CRYPT_DATA_BLOB datablob; - WCHAR* pszPassword; - size_t pwd_len = 0; - int str_w_len = 0; - const char *cert_showfilename_error = blob ? - "(memory blob)" : data->set.ssl.primary.clientcert; - curlx_unicodefree(cert_path); - if(fInCert) { - long cert_tell = 0; - bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0; - if(continue_reading) - cert_tell = ftell(fInCert); - if(cert_tell < 0) - continue_reading = FALSE; - else - certsize = (size_t)cert_tell; - if(continue_reading) - continue_reading = fseek(fInCert, 0, SEEK_SET) == 0; - if(continue_reading) - certdata = malloc(certsize + 1); - if((!certdata) || - ((int) fread(certdata, certsize, 1, fInCert) != 1)) - continue_reading = FALSE; - fclose(fInCert); - if(!continue_reading) { - failf(data, "schannel: Failed to read cert file %s", - data->set.ssl.primary.clientcert); - free(certdata); - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Convert key-pair data to the in-memory certificate store */ - datablob.pbData = (BYTE*)certdata; - datablob.cbData = (DWORD)certsize; - - if(data->set.ssl.key_passwd != NULL) - pwd_len = strlen(data->set.ssl.key_passwd); - pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1)); - if(pszPassword) { - if(pwd_len > 0) - str_w_len = MultiByteToWideChar(CP_UTF8, - MB_ERR_INVALID_CHARS, - data->set.ssl.key_passwd, (int)pwd_len, - pszPassword, (int)(pwd_len + 1)); - - if((str_w_len >= 0) && (str_w_len <= (int)pwd_len)) - pszPassword[str_w_len] = 0; - else - pszPassword[0] = 0; - - cert_store = PFXImportCertStore(&datablob, pszPassword, 0); - free(pszPassword); - } - if(!blob) - free(certdata); - if(cert_store == NULL) { - DWORD errorcode = GetLastError(); - if(errorcode == ERROR_INVALID_PASSWORD) - failf(data, "schannel: Failed to import cert file %s, " - "password is bad", - cert_showfilename_error); - else - failf(data, "schannel: Failed to import cert file %s, " - "last error is 0x%x", - cert_showfilename_error, errorcode); - return CURLE_SSL_CERTPROBLEM; - } - - client_certs[0] = CertFindCertificateInStore( - cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, - CERT_FIND_ANY, NULL, NULL); - - if(client_certs[0] == NULL) { - failf(data, "schannel: Failed to get certificate from file %s" - ", last error is 0x%x", - cert_showfilename_error, GetLastError()); - CertCloseStore(cert_store, 0); - return CURLE_SSL_CERTPROBLEM; - } - + if(fInCert || blob) { + /* Reading a .P12 or .pfx file, like the example at bottom of + https://social.msdn.microsoft.com/Forums/windowsdesktop/ + en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5 + */ + CRYPT_DATA_BLOB datablob; + WCHAR* pszPassword; + size_t pwd_len = 0; + int str_w_len = 0; + const char *cert_showfilename_error = blob ? + "(memory blob)" : data->set.ssl.primary.clientcert; + curlx_unicodefree(cert_path); + if(fInCert) { + long cert_tell = 0; + bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0; + if(continue_reading) + cert_tell = ftell(fInCert); + if(cert_tell < 0) + continue_reading = FALSE; + else + certsize = (size_t)cert_tell; + if(continue_reading) + continue_reading = fseek(fInCert, 0, SEEK_SET) == 0; + if(continue_reading) + certdata = malloc(certsize + 1); + if((!certdata) || + ((int) fread(certdata, certsize, 1, fInCert) != 1)) + continue_reading = FALSE; + fclose(fInCert); + if(!continue_reading) { + failf(data, "schannel: Failed to read cert file %s", + data->set.ssl.primary.clientcert); + free(certdata); + return CURLE_SSL_CERTPROBLEM; + } + } + + /* Convert key-pair data to the in-memory certificate store */ + datablob.pbData = (BYTE*)certdata; + datablob.cbData = (DWORD)certsize; + + if(data->set.ssl.key_passwd != NULL) + pwd_len = strlen(data->set.ssl.key_passwd); + pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1)); + if(pszPassword) { + if(pwd_len > 0) + str_w_len = MultiByteToWideChar(CP_UTF8, + MB_ERR_INVALID_CHARS, + data->set.ssl.key_passwd, (int)pwd_len, + pszPassword, (int)(pwd_len + 1)); + + if((str_w_len >= 0) && (str_w_len <= (int)pwd_len)) + pszPassword[str_w_len] = 0; + else + pszPassword[0] = 0; + + cert_store = PFXImportCertStore(&datablob, pszPassword, 0); + free(pszPassword); + } + if(!blob) + free(certdata); + if(cert_store == NULL) { + DWORD errorcode = GetLastError(); + if(errorcode == ERROR_INVALID_PASSWORD) + failf(data, "schannel: Failed to import cert file %s, " + "password is bad", + cert_showfilename_error); + else + failf(data, "schannel: Failed to import cert file %s, " + "last error is 0x%x", + cert_showfilename_error, errorcode); + return CURLE_SSL_CERTPROBLEM; + } + + client_certs[0] = CertFindCertificateInStore( + cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, + CERT_FIND_ANY, NULL, NULL); + + if(client_certs[0] == NULL) { + failf(data, "schannel: Failed to get certificate from file %s" + ", last error is 0x%x", + cert_showfilename_error, GetLastError()); + CertCloseStore(cert_store, 0); + return CURLE_SSL_CERTPROBLEM; + } + schannel_cred.cCreds = 1; schannel_cred.paCred = client_certs; } else { - cert_store = - CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0, - (HCRYPTPROV)NULL, - CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name, - cert_store_path); - if(!cert_store) { - failf(data, "schannel: Failed to open cert store %x %s, " - "last error is 0x%x", - cert_store_name, cert_store_path, GetLastError()); - free(cert_store_path); - curlx_unicodefree(cert_path); - return CURLE_SSL_CERTPROBLEM; - } - free(cert_store_path); - - cert_thumbprint.pbData = cert_thumbprint_data; - cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN; - - if(!CryptStringToBinary(cert_thumbprint_str, - CERT_THUMBPRINT_STR_LEN, - CRYPT_STRING_HEX, - cert_thumbprint_data, - &cert_thumbprint.cbData, - NULL, NULL)) { - curlx_unicodefree(cert_path); - CertCloseStore(cert_store, 0); - return CURLE_SSL_CERTPROBLEM; - } - - client_certs[0] = CertFindCertificateInStore( - cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, - CERT_FIND_HASH, &cert_thumbprint, NULL); - - curlx_unicodefree(cert_path); - - if(client_certs[0]) { - schannel_cred.cCreds = 1; - schannel_cred.paCred = client_certs; - } - else { - /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ - CertCloseStore(cert_store, 0); - return CURLE_SSL_CERTPROBLEM; - } + cert_store = + CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0, + (HCRYPTPROV)NULL, + CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name, + cert_store_path); + if(!cert_store) { + failf(data, "schannel: Failed to open cert store %x %s, " + "last error is 0x%x", + cert_store_name, cert_store_path, GetLastError()); + free(cert_store_path); + curlx_unicodefree(cert_path); + return CURLE_SSL_CERTPROBLEM; + } + free(cert_store_path); + + cert_thumbprint.pbData = cert_thumbprint_data; + cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN; + + if(!CryptStringToBinary(cert_thumbprint_str, + CERT_THUMBPRINT_STR_LEN, + CRYPT_STRING_HEX, + cert_thumbprint_data, + &cert_thumbprint.cbData, + NULL, NULL)) { + curlx_unicodefree(cert_path); + CertCloseStore(cert_store, 0); + return CURLE_SSL_CERTPROBLEM; + } + + client_certs[0] = CertFindCertificateInStore( + cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, + CERT_FIND_HASH, &cert_thumbprint, NULL); + + curlx_unicodefree(cert_path); + + if(client_certs[0]) { + schannel_cred.cCreds = 1; + schannel_cred.paCred = client_certs; + } + else { + /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ + CertCloseStore(cert_store, 0); + return CURLE_SSL_CERTPROBLEM; + } } CertCloseStore(cert_store, 0); } #else - if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { + if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { failf(data, "schannel: client cert support not built in"); return CURLE_NOT_BUILT_IN; } #endif /* allocate memory for the re-usable credential handle */ - BACKEND->cred = (struct Curl_schannel_cred *) - calloc(1, sizeof(struct Curl_schannel_cred)); + BACKEND->cred = (struct Curl_schannel_cred *) + calloc(1, sizeof(struct Curl_schannel_cred)); if(!BACKEND->cred) { failf(data, "schannel: unable to allocate memory"); @@ -794,7 +794,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) BACKEND->cred->refcount = 1; /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx - */ + */ sspi_status = s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, @@ -811,15 +811,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); Curl_safefree(BACKEND->cred); switch(sspi_status) { - case SEC_E_INSUFFICIENT_MEMORY: - return CURLE_OUT_OF_MEMORY; - case SEC_E_NO_CREDENTIALS: - case SEC_E_SECPKG_NOT_FOUND: - case SEC_E_NOT_OWNER: - case SEC_E_UNKNOWN_CREDENTIALS: - case SEC_E_INTERNAL_ERROR: - default: - return CURLE_SSL_CONNECT_ERROR; + case SEC_E_INSUFFICIENT_MEMORY: + return CURLE_OUT_OF_MEMORY; + case SEC_E_NO_CREDENTIALS: + case SEC_E_SECPKG_NOT_FOUND: + case SEC_E_NOT_OWNER: + case SEC_E_UNKNOWN_CREDENTIALS: + case SEC_E_INTERNAL_ERROR: + default: + return CURLE_SSL_CONNECT_ERROR; } } } @@ -841,7 +841,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) unsigned short* list_len = NULL; /* The first four bytes will be an unsigned int indicating number - of bytes of data in the rest of the buffer. */ + of bytes of data in the rest of the buffer. */ extension_len = (unsigned int *)(&alpn_buffer[cur]); cur += sizeof(unsigned int); @@ -896,14 +896,14 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) ISC_REQ_STREAM; /* allocate memory for the security context handle */ - BACKEND->ctxt = (struct Curl_schannel_ctxt *) - calloc(1, sizeof(struct Curl_schannel_ctxt)); + BACKEND->ctxt = (struct Curl_schannel_ctxt *) + calloc(1, sizeof(struct Curl_schannel_ctxt)); if(!BACKEND->ctxt) { failf(data, "schannel: unable to allocate memory"); return CURLE_OUT_OF_MEMORY; } - host_name = curlx_convert_UTF8_to_tchar(hostname); + host_name = curlx_convert_UTF8_to_tchar(hostname); if(!host_name) return CURLE_OUT_OF_MEMORY; @@ -920,35 +920,35 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) 0, &BACKEND->ctxt->ctxt_handle, &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp); - curlx_unicodefree(host_name); + curlx_unicodefree(host_name); if(sspi_status != SEC_I_CONTINUE_NEEDED) { char buffer[STRERROR_LEN]; Curl_safefree(BACKEND->ctxt); switch(sspi_status) { - case SEC_E_INSUFFICIENT_MEMORY: - failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_OUT_OF_MEMORY; - case SEC_E_WRONG_PRINCIPAL: - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_PEER_FAILED_VERIFICATION; - /* - case SEC_E_INVALID_HANDLE: - case SEC_E_INVALID_TOKEN: - case SEC_E_LOGON_DENIED: - case SEC_E_TARGET_UNKNOWN: - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - case SEC_E_INTERNAL_ERROR: - case SEC_E_NO_CREDENTIALS: - case SEC_E_UNSUPPORTED_FUNCTION: - case SEC_E_APPLICATION_PROTOCOL_MISMATCH: - */ - default: - failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_SSL_CONNECT_ERROR; + case SEC_E_INSUFFICIENT_MEMORY: + failf(data, "schannel: initial InitializeSecurityContext failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_OUT_OF_MEMORY; + case SEC_E_WRONG_PRINCIPAL: + failf(data, "schannel: SNI or certificate check failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_PEER_FAILED_VERIFICATION; + /* + case SEC_E_INVALID_HANDLE: + case SEC_E_INVALID_TOKEN: + case SEC_E_LOGON_DENIED: + case SEC_E_TARGET_UNKNOWN: + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + case SEC_E_INTERNAL_ERROR: + case SEC_E_NO_CREDENTIALS: + case SEC_E_UNSUPPORTED_FUNCTION: + case SEC_E_APPLICATION_PROTOCOL_MISMATCH: + */ + default: + failf(data, "schannel: initial InitializeSecurityContext failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_SSL_CONNECT_ERROR; } } @@ -994,12 +994,12 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) SECURITY_STATUS sspi_status = SEC_E_OK; CURLcode result; bool doread; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; -#else - char * const hostname = conn->host.name; -#endif +#else + char * const hostname = conn->host.name; +#endif const char *pubkey_ptr; doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; @@ -1107,18 +1107,18 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer, BACKEND->encdata_offset); - host_name = curlx_convert_UTF8_to_tchar(hostname); + host_name = curlx_convert_UTF8_to_tchar(hostname); if(!host_name) return CURLE_OUT_OF_MEMORY; /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx - */ + */ 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); - curlx_unicodefree(host_name); + curlx_unicodefree(host_name); /* free buffer for received handshake data */ Curl_safefree(inbuf[0].pvBuffer); @@ -1173,33 +1173,33 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) else { char buffer[STRERROR_LEN]; switch(sspi_status) { - case SEC_E_INSUFFICIENT_MEMORY: - failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_OUT_OF_MEMORY; - case SEC_E_WRONG_PRINCIPAL: - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_PEER_FAILED_VERIFICATION; - case SEC_E_UNTRUSTED_ROOT: - failf(data, "schannel: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_PEER_FAILED_VERIFICATION; - /* - case SEC_E_INVALID_HANDLE: - case SEC_E_INVALID_TOKEN: - case SEC_E_LOGON_DENIED: - case SEC_E_TARGET_UNKNOWN: - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - case SEC_E_INTERNAL_ERROR: - case SEC_E_NO_CREDENTIALS: - case SEC_E_UNSUPPORTED_FUNCTION: - case SEC_E_APPLICATION_PROTOCOL_MISMATCH: - */ - default: - failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - return CURLE_SSL_CONNECT_ERROR; + case SEC_E_INSUFFICIENT_MEMORY: + failf(data, "schannel: next InitializeSecurityContext failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_OUT_OF_MEMORY; + case SEC_E_WRONG_PRINCIPAL: + failf(data, "schannel: SNI or certificate check failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_PEER_FAILED_VERIFICATION; + case SEC_E_UNTRUSTED_ROOT: + failf(data, "schannel: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_PEER_FAILED_VERIFICATION; + /* + case SEC_E_INVALID_HANDLE: + case SEC_E_INVALID_TOKEN: + case SEC_E_LOGON_DENIED: + case SEC_E_TARGET_UNKNOWN: + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + case SEC_E_INTERNAL_ERROR: + case SEC_E_NO_CREDENTIALS: + case SEC_E_UNSUPPORTED_FUNCTION: + case SEC_E_APPLICATION_PROTOCOL_MISMATCH: + */ + default: + failf(data, "schannel: next InitializeSecurityContext failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + return CURLE_SSL_CONNECT_ERROR; } } @@ -1308,7 +1308,7 @@ struct Adder_args struct connectdata *conn; CURLcode result; int idx; - int certs_count; + int certs_count; }; static bool @@ -1319,9 +1319,9 @@ add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, void *raw_arg) if(valid_cert_encoding(ccert_context)) { const char *beg = (const char *) ccert_context->pbCertEncoded; const char *end = beg + ccert_context->cbCertEncoded; - int insert_index = (args->certs_count - 1) - args->idx; - args->result = Curl_extract_certinfo(args->conn, insert_index, beg, end); - args->idx++; + int insert_index = (args->certs_count - 1) - args->idx; + args->result = Curl_extract_certinfo(args->conn, insert_index, beg, end); + args->idx++; } return args->result == CURLE_OK; } @@ -1368,10 +1368,10 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) #ifdef HAS_ALPN if(BACKEND->use_alpn) { - sspi_status = - s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_APPLICATION_PROTOCOL, - &alpn_result); + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_APPLICATION_PROTOCOL, + &alpn_result); if(sspi_status != SEC_E_OK) { failf(data, "schannel: failed to retrieve ALPN result"); @@ -1382,21 +1382,21 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) SecApplicationProtocolNegotiationStatus_Success) { infof(data, "schannel: ALPN, server accepted to use %.*s\n", - alpn_result.ProtocolIdSize, alpn_result.ProtocolId); + alpn_result.ProtocolIdSize, alpn_result.ProtocolId); #ifdef USE_NGHTTP2 if(alpn_result.ProtocolIdSize == NGHTTP2_PROTO_VERSION_ID_LEN && !memcmp(NGHTTP2_PROTO_VERSION_ID, alpn_result.ProtocolId, - NGHTTP2_PROTO_VERSION_ID_LEN)) { + NGHTTP2_PROTO_VERSION_ID_LEN)) { conn->negnpn = CURL_HTTP_VERSION_2; } else #endif - if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH && - !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId, - ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; - } + if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH && + !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId, + ALPN_HTTP_1_1_LENGTH)) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } } else infof(data, "ALPN, server did not agree to a protocol\n"); @@ -1408,7 +1408,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) /* save the current session data for possible re-use */ if(SSL_SET_OPTION(primary.sessionid)) { bool incache; - struct Curl_schannel_cred *old_cred = NULL; + struct Curl_schannel_cred *old_cred = NULL; Curl_ssl_sessionid_lock(conn); incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, @@ -1424,7 +1424,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) } if(!incache) { result = Curl_ssl_addsessionid(conn, (void *)BACKEND->cred, - sizeof(struct Curl_schannel_cred), + sizeof(struct Curl_schannel_cred), sockindex); if(result) { Curl_ssl_sessionid_unlock(conn); @@ -1443,10 +1443,10 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) if(data->set.ssl.certinfo) { int certs_count = 0; - sspi_status = - s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &ccert_context); + sspi_status = + s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &ccert_context); if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) { failf(data, "schannel: failed to retrieve remote cert context"); @@ -1460,7 +1460,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) struct Adder_args args; args.conn = conn; args.idx = 0; - args.certs_count = certs_count; + args.certs_count = certs_count; traverse_cert_store(ccert_context, add_cert_to_certinfo, &args); result = args.result; } @@ -1482,7 +1482,7 @@ schannel_connect_common(struct connectdata *conn, int sockindex, struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; curl_socket_t sockfd = conn->sock[sockindex]; - timediff_t timeout_ms; + timediff_t timeout_ms; int what; /* check if the connection has already been established */ @@ -1678,10 +1678,10 @@ schannel_send(struct connectdata *conn, int sockindex, /* send entire message or fail */ while(len > (size_t)written) { - ssize_t this_write = 0; + ssize_t this_write = 0; int what; - timediff_t timeout_ms = Curl_timeleft(conn->data, NULL, FALSE); - if(timeout_ms < 0) { + timediff_t timeout_ms = Curl_timeleft(conn->data, NULL, FALSE); + if(timeout_ms < 0) { /* we already got the timeout */ failf(conn->data, "schannel: timed out sending data " "(bytes sent: %zd)", written); @@ -1689,9 +1689,9 @@ schannel_send(struct connectdata *conn, int sockindex, written = -1; break; } - else if(!timeout_ms) - timeout_ms = TIMEDIFF_T_MAX; - what = SOCKET_WRITABLE(conn->sock[sockindex], timeout_ms); + else if(!timeout_ms) + timeout_ms = TIMEDIFF_T_MAX; + what = SOCKET_WRITABLE(conn->sock[sockindex], timeout_ms); if(what < 0) { /* fatal error */ failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO); @@ -1785,8 +1785,8 @@ schannel_recv(struct connectdata *conn, int sockindex, } else if(!len) { /* It's debatable what to return when !len. Regardless we can't return - 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. + 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. */ ; /* do nothing */ } @@ -1796,7 +1796,7 @@ schannel_recv(struct connectdata *conn, int sockindex, if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE || BACKEND->encdata_length < min_encdata_length) { reallocated_length = BACKEND->encdata_offset + - CURL_SCHANNEL_BUFFER_FREE_SIZE; + CURL_SCHANNEL_BUFFER_FREE_SIZE; if(reallocated_length < min_encdata_length) { reallocated_length = min_encdata_length; } @@ -1864,7 +1864,7 @@ schannel_recv(struct connectdata *conn, int sockindex, InitSecBufferDesc(&inbuf_desc, inbuf, 4); /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx - */ + */ sspi_status = s_pSecFn->DecryptMessage(&BACKEND->ctxt->ctxt_handle, &inbuf_desc, 0, NULL); @@ -1880,7 +1880,7 @@ schannel_recv(struct connectdata *conn, int sockindex, /* increase buffer in order to fit the received amount of data */ size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ? - inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE; + inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE; if(BACKEND->decdata_length - BACKEND->decdata_offset < size || BACKEND->decdata_length < len) { /* increase internal decrypted data buffer */ @@ -1950,7 +1950,7 @@ schannel_recv(struct connectdata *conn, int sockindex, if(BACKEND->encdata_offset) { *err = CURLE_RECV_ERROR; infof(data, "schannel: can't renogotiate, " - "encrypted data available\n"); + "encrypted data available\n"); goto cleanup; } /* begin renegotiation */ @@ -1987,9 +1987,9 @@ schannel_recv(struct connectdata *conn, int sockindex, goto cleanup; } else { -#ifndef CURL_DISABLE_VERBOSE_STRINGS +#ifndef CURL_DISABLE_VERBOSE_STRINGS char buffer[STRERROR_LEN]; -#endif +#endif *err = CURLE_RECV_ERROR; infof(data, "schannel: failed to read data from server: %s\n", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); @@ -2005,25 +2005,25 @@ schannel_recv(struct connectdata *conn, int sockindex, "schannel: decrypted data buffer: offset %zu length %zu\n", BACKEND->decdata_offset, BACKEND->decdata_length)); - cleanup: + cleanup: /* Warning- there is no guarantee the encdata state is valid at this point */ DEBUGF(infof(data, "schannel: schannel_recv cleanup\n")); /* Error if the connection has closed without a close_notify. - - The behavior here is a matter of debate. We don't want to be vulnerable - to a truncation attack however there's some browser precedent for - ignoring the close_notify for compatibility reasons. - - Additionally, Windows 2000 (v5.0) is a special case since it seems it - doesn't return close_notify. In that case if the connection was closed we - assume it was graceful (close_notify) since there doesn't seem to be a - way to tell. + + The behavior here is a matter of debate. We don't want to be vulnerable + to a truncation attack however there's some browser precedent for + ignoring the close_notify for compatibility reasons. + + Additionally, Windows 2000 (v5.0) is a special case since it seems it + doesn't return close_notify. In that case if the connection was closed we + assume it was graceful (close_notify) since there doesn't seem to be a + way to tell. */ if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed && !BACKEND->recv_sspi_close_notify) { - bool isWin2k = curlx_verify_windows_version(5, 0, PLATFORM_WINNT, - VERSION_EQUAL); + bool isWin2k = curlx_verify_windows_version(5, 0, PLATFORM_WINNT, + VERSION_EQUAL); if(isWin2k && sspi_status == SEC_E_OK) BACKEND->recv_sspi_close_notify = true; @@ -2035,7 +2035,7 @@ schannel_recv(struct connectdata *conn, 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; if(size) { @@ -2052,11 +2052,11 @@ schannel_recv(struct connectdata *conn, int sockindex, } if(!*err && !BACKEND->recv_connection_closed) - *err = CURLE_AGAIN; + *err = CURLE_AGAIN; - /* It's debatable what to return when !len. We could return whatever error - we got from decryption but instead we override here so the return is - consistent. + /* It's debatable what to return when !len. We could return whatever error + we got from decryption but instead we override here so the return is + consistent. */ if(!len) *err = CURLE_OK; @@ -2106,7 +2106,7 @@ static void Curl_schannel_close(struct connectdata *conn, int sockindex) static void Curl_schannel_session_free(void *ptr) { /* this is expected to be called under sessionid lock */ - struct Curl_schannel_cred *cred = ptr; + struct Curl_schannel_cred *cred = ptr; cred->refcount--; if(cred->refcount == 0) { @@ -2122,12 +2122,12 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) */ struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; -#else - char * const hostname = conn->host.name; -#endif +#else + char * const hostname = conn->host.name; +#endif DEBUGASSERT(data); @@ -2156,7 +2156,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); } - host_name = curlx_convert_UTF8_to_tchar(hostname); + host_name = curlx_convert_UTF8_to_tchar(hostname); if(!host_name) return CURLE_OUT_OF_MEMORY; @@ -2178,7 +2178,7 @@ static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp); - curlx_unicodefree(host_name); + curlx_unicodefree(host_name); if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) { /* send close message which is in output buffer */ @@ -2287,8 +2287,8 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, SECURITY_STATUS sspi_status; const char *x509_der; DWORD x509_der_len; - struct Curl_X509certificate x509_parsed; - struct Curl_asn1Element *pubkey; + struct Curl_X509certificate x509_parsed; + struct Curl_asn1Element *pubkey; sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, @@ -2304,7 +2304,7 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, if(!(((pCertContextServer->dwCertEncodingType & X509_ASN_ENCODING) != 0) && - (pCertContextServer->cbCertEncoded > 0))) + (pCertContextServer->cbCertEncoded > 0))) break; x509_der = (const char *)pCertContextServer->pbCertEncoded; @@ -2353,7 +2353,7 @@ static void Curl_schannel_checksum(const unsigned char *input, memset(checksum, 0, checksumlen); if(!CryptAcquireContext(&hProv, NULL, NULL, provType, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) return; /* failed */ do { @@ -2395,9 +2395,9 @@ static CURLcode Curl_schannel_md5sum(unsigned char *input, } static CURLcode Curl_schannel_sha256sum(const unsigned char *input, - size_t inputlen, - unsigned char *sha256sum, - size_t sha256len) + size_t inputlen, + unsigned char *sha256sum, + size_t sha256len) { Curl_schannel_checksum(input, inputlen, sha256sum, sha256len, PROV_RSA_AES, CALG_SHA_256); diff --git a/contrib/libs/curl/lib/vtls/schannel.h b/contrib/libs/curl/lib/vtls/schannel.h index 085b3f455c..a361c4ca5d 100644 --- a/contrib/libs/curl/lib/vtls/schannel.h +++ b/contrib/libs/curl/lib/vtls/schannel.h @@ -8,11 +8,11 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al. - * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -70,20 +70,20 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex); #endif #endif -struct Curl_schannel_cred { +struct Curl_schannel_cred { CredHandle cred_handle; TimeStamp time_stamp; int refcount; }; -struct Curl_schannel_ctxt { +struct Curl_schannel_ctxt { CtxtHandle ctxt_handle; TimeStamp time_stamp; }; struct ssl_backend_data { - struct Curl_schannel_cred *cred; - struct Curl_schannel_ctxt *ctxt; + struct Curl_schannel_cred *cred; + struct Curl_schannel_ctxt *ctxt; SecPkgContext_StreamSizes stream_sizes; size_t encdata_length, decdata_length; size_t encdata_offset, decdata_offset; diff --git a/contrib/libs/curl/lib/vtls/schannel_verify.c b/contrib/libs/curl/lib/vtls/schannel_verify.c index 31b3b2f02f..94462d1812 100644 --- a/contrib/libs/curl/lib/vtls/schannel_verify.c +++ b/contrib/libs/curl/lib/vtls/schannel_verify.c @@ -7,11 +7,11 @@ * * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de> * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> - * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -45,7 +45,7 @@ #include "curl_multibyte.h" #include "curl_printf.h" #include "hostcheck.h" -#include "version_win32.h" +#include "version_win32.h" /* The last #include file should be: */ #include "curl_memory.h" @@ -57,7 +57,7 @@ #define BEGIN_CERT "-----BEGIN CERTIFICATE-----" #define END_CERT "\n-----END CERTIFICATE-----" -struct cert_chain_engine_config_win7 { +struct cert_chain_engine_config_win7 { DWORD cbSize; HCERTSTORE hRestrictedRoot; HCERTSTORE hRestrictedTrust; @@ -70,7 +70,7 @@ struct cert_chain_engine_config_win7 { DWORD CycleDetectionModulus; HCERTSTORE hExclusiveRoot; HCERTSTORE hExclusiveTrustedPeople; -}; +}; static int is_cr_or_lf(char c) { @@ -94,13 +94,13 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, int num_certs = 0; size_t END_CERT_LEN; - ca_file_tstr = curlx_convert_UTF8_to_tchar((char *)ca_file); + ca_file_tstr = curlx_convert_UTF8_to_tchar((char *)ca_file); if(!ca_file_tstr) { char buffer[STRERROR_LEN]; failf(data, "schannel: invalid path name for CA file '%s': %s", - ca_file, - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -112,7 +112,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, */ ca_file_handle = CreateFile(ca_file_tstr, GENERIC_READ, - FILE_SHARE_READ, + FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, @@ -121,8 +121,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: failed to open CA file '%s': %s", - ca_file, - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -131,8 +131,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: failed to determine size of CA file '%s': %s", - ca_file, - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -162,8 +162,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: failed to read from CA file '%s': %s", - ca_file, - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -227,7 +227,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, "schannel: failed to extract certificate from CA file " "'%s': %s", ca_file, - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -256,8 +256,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, "schannel: failed to add certificate from CA file '%s' " "to certificate store: %s", ca_file, - Curl_winapi_strerror(GetLastError(), buffer, - sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, + sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -288,138 +288,138 @@ cleanup: CloseHandle(ca_file_handle); } Curl_safefree(ca_file_buffer); - curlx_unicodefree(ca_file_tstr); + curlx_unicodefree(ca_file_tstr); return result; } -/* - * Returns the number of characters necessary to populate all the host_names. - * If host_names is not NULL, populate it with all the host names. Each string - * in the host_names is null-terminated and the last string is double - * null-terminated. If no DNS names are found, a single null-terminated empty - * string is returned. - */ -static DWORD cert_get_name_string(struct Curl_easy *data, - CERT_CONTEXT *cert_context, - LPTSTR host_names, - DWORD length) -{ - DWORD actual_length = 0; - BOOL compute_content = FALSE; - CERT_INFO *cert_info = NULL; - CERT_EXTENSION *extension = NULL; - CRYPT_DECODE_PARA decode_para = {0, 0, 0}; - CERT_ALT_NAME_INFO *alt_name_info = NULL; - DWORD alt_name_info_size = 0; - BOOL ret_val = FALSE; - LPTSTR current_pos = NULL; - DWORD i; - - /* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */ - if(curlx_verify_windows_version(6, 2, PLATFORM_WINNT, - VERSION_GREATER_THAN_EQUAL)) { -#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG - /* CertGetNameString will provide the 8-bit character string without - * any decoding */ - DWORD name_flags = - CERT_NAME_DISABLE_IE4_UTF8_FLAG | CERT_NAME_SEARCH_ALL_NAMES_FLAG; - actual_length = CertGetNameString(cert_context, - CERT_NAME_DNS_TYPE, - name_flags, - NULL, - host_names, - length); - return actual_length; -#endif - } - - compute_content = host_names != NULL && length != 0; - - /* Initialize default return values. */ - actual_length = 1; - if(compute_content) { - *host_names = '\0'; - } - - if(!cert_context) { - failf(data, "schannel: Null certificate context."); - return actual_length; - } - - cert_info = cert_context->pCertInfo; - if(!cert_info) { - failf(data, "schannel: Null certificate info."); - return actual_length; - } - - extension = CertFindExtension(szOID_SUBJECT_ALT_NAME2, - cert_info->cExtension, - cert_info->rgExtension); - if(!extension) { - failf(data, "schannel: CertFindExtension() returned no extension."); - return actual_length; - } - - decode_para.cbSize = sizeof(CRYPT_DECODE_PARA); - - ret_val = - CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - szOID_SUBJECT_ALT_NAME2, - extension->Value.pbData, - extension->Value.cbData, - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, - &decode_para, - &alt_name_info, - &alt_name_info_size); - if(!ret_val) { - failf(data, - "schannel: CryptDecodeObjectEx() returned no alternate name " - "information."); - return actual_length; - } - - current_pos = host_names; - - /* Iterate over the alternate names and populate host_names. */ - for(i = 0; i < alt_name_info->cAltEntry; i++) { - const CERT_ALT_NAME_ENTRY *entry = &alt_name_info->rgAltEntry[i]; - wchar_t *dns_w = NULL; - size_t current_length = 0; - - if(entry->dwAltNameChoice != CERT_ALT_NAME_DNS_NAME) { - continue; - } - if(entry->pwszDNSName == NULL) { - infof(data, "schannel: Empty DNS name."); - continue; - } - current_length = wcslen(entry->pwszDNSName) + 1; - if(!compute_content) { - actual_length += (DWORD)current_length; - continue; - } - /* Sanity check to prevent buffer overrun. */ - if((actual_length + current_length) > length) { - failf(data, "schannel: Not enough memory to list all host names."); - break; - } - dns_w = entry->pwszDNSName; - /* pwszDNSName is in ia5 string format and hence doesn't contain any - * non-ascii characters. */ - while(*dns_w != '\0') { - *current_pos++ = (char)(*dns_w++); - } - *current_pos++ = '\0'; - actual_length += (DWORD)current_length; - } - if(compute_content) { - /* Last string has double null-terminator. */ - *current_pos = '\0'; - } - return actual_length; -} - +/* + * Returns the number of characters necessary to populate all the host_names. + * If host_names is not NULL, populate it with all the host names. Each string + * in the host_names is null-terminated and the last string is double + * null-terminated. If no DNS names are found, a single null-terminated empty + * string is returned. + */ +static DWORD cert_get_name_string(struct Curl_easy *data, + CERT_CONTEXT *cert_context, + LPTSTR host_names, + DWORD length) +{ + DWORD actual_length = 0; + BOOL compute_content = FALSE; + CERT_INFO *cert_info = NULL; + CERT_EXTENSION *extension = NULL; + CRYPT_DECODE_PARA decode_para = {0, 0, 0}; + CERT_ALT_NAME_INFO *alt_name_info = NULL; + DWORD alt_name_info_size = 0; + BOOL ret_val = FALSE; + LPTSTR current_pos = NULL; + DWORD i; + + /* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */ + if(curlx_verify_windows_version(6, 2, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) { +#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG + /* CertGetNameString will provide the 8-bit character string without + * any decoding */ + DWORD name_flags = + CERT_NAME_DISABLE_IE4_UTF8_FLAG | CERT_NAME_SEARCH_ALL_NAMES_FLAG; + actual_length = CertGetNameString(cert_context, + CERT_NAME_DNS_TYPE, + name_flags, + NULL, + host_names, + length); + return actual_length; +#endif + } + + compute_content = host_names != NULL && length != 0; + + /* Initialize default return values. */ + actual_length = 1; + if(compute_content) { + *host_names = '\0'; + } + + if(!cert_context) { + failf(data, "schannel: Null certificate context."); + return actual_length; + } + + cert_info = cert_context->pCertInfo; + if(!cert_info) { + failf(data, "schannel: Null certificate info."); + return actual_length; + } + + extension = CertFindExtension(szOID_SUBJECT_ALT_NAME2, + cert_info->cExtension, + cert_info->rgExtension); + if(!extension) { + failf(data, "schannel: CertFindExtension() returned no extension."); + return actual_length; + } + + decode_para.cbSize = sizeof(CRYPT_DECODE_PARA); + + ret_val = + CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + szOID_SUBJECT_ALT_NAME2, + extension->Value.pbData, + extension->Value.cbData, + CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, + &decode_para, + &alt_name_info, + &alt_name_info_size); + if(!ret_val) { + failf(data, + "schannel: CryptDecodeObjectEx() returned no alternate name " + "information."); + return actual_length; + } + + current_pos = host_names; + + /* Iterate over the alternate names and populate host_names. */ + for(i = 0; i < alt_name_info->cAltEntry; i++) { + const CERT_ALT_NAME_ENTRY *entry = &alt_name_info->rgAltEntry[i]; + wchar_t *dns_w = NULL; + size_t current_length = 0; + + if(entry->dwAltNameChoice != CERT_ALT_NAME_DNS_NAME) { + continue; + } + if(entry->pwszDNSName == NULL) { + infof(data, "schannel: Empty DNS name."); + continue; + } + current_length = wcslen(entry->pwszDNSName) + 1; + if(!compute_content) { + actual_length += (DWORD)current_length; + continue; + } + /* Sanity check to prevent buffer overrun. */ + if((actual_length + current_length) > length) { + failf(data, "schannel: Not enough memory to list all host names."); + break; + } + dns_w = entry->pwszDNSName; + /* pwszDNSName is in ia5 string format and hence doesn't contain any + * non-ascii characters. */ + while(*dns_w != '\0') { + *current_pos++ = (char)(*dns_w++); + } + *current_pos++ = '\0'; + actual_length += (DWORD)current_length; + } + if(compute_content) { + /* Last string has double null-terminator. */ + *current_pos = '\0'; + } + return actual_length; +} + static CURLcode verify_host(struct Curl_easy *data, CERT_CONTEXT *pCertContextServer, const char * const conn_hostname) @@ -431,7 +431,7 @@ static CURLcode verify_host(struct Curl_easy *data, DWORD actual_len = 0; /* Determine the size of the string needed for the cert hostname */ - len = cert_get_name_string(data, pCertContextServer, NULL, 0); + len = cert_get_name_string(data, pCertContextServer, NULL, 0); if(len == 0) { failf(data, "schannel: CertGetNameString() returned no " @@ -448,8 +448,8 @@ static CURLcode verify_host(struct Curl_easy *data, result = CURLE_OUT_OF_MEMORY; goto cleanup; } - actual_len = cert_get_name_string( - data, pCertContextServer, (LPTSTR)cert_hostname_buff, len); + actual_len = cert_get_name_string( + data, pCertContextServer, (LPTSTR)cert_hostname_buff, len); /* Sanity check */ if(actual_len != len) { @@ -476,7 +476,7 @@ static CURLcode verify_host(struct Curl_easy *data, * is acceptable since both values are assumed to use ASCII * (or some equivalent) encoding */ - cert_hostname = curlx_convert_tchar_to_UTF8( + cert_hostname = curlx_convert_tchar_to_UTF8( &cert_hostname_buff[cert_hostname_buff_index]); if(!cert_hostname) { result = CURLE_OUT_OF_MEMORY; @@ -508,7 +508,7 @@ static CURLcode verify_host(struct Curl_easy *data, result = CURLE_PEER_FAILED_VERIFICATION; } - curlx_unicodefree(cert_hostname); + curlx_unicodefree(cert_hostname); } } @@ -522,7 +522,7 @@ static CURLcode verify_host(struct Curl_easy *data, failf(data, "schannel: server certificate name verification failed"); cleanup: - curlx_unicodefree(cert_hostname_buff); + curlx_unicodefree(cert_hostname_buff); return result; } @@ -537,13 +537,13 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) const CERT_CHAIN_CONTEXT *pChainContext = NULL; HCERTCHAINENGINE cert_chain_engine = NULL; HCERTSTORE trust_store = NULL; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY const char * const conn_hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; -#else - const char * const conn_hostname = conn->host.name; -#endif +#else + const char * const conn_hostname = conn->host.name; +#endif sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, @@ -564,7 +564,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) * 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, 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; @@ -579,7 +579,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) if(!trust_store) { char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate store: %s", - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } else { @@ -589,7 +589,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) } if(result == CURLE_OK) { - struct cert_chain_engine_config_win7 engine_config; + struct cert_chain_engine_config_win7 engine_config; BOOL create_engine_result; memset(&engine_config, 0, sizeof(engine_config)); @@ -608,7 +608,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate chain engine: %s", - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } } @@ -631,7 +631,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) &pChainContext)) { char buffer[STRERROR_LEN]; failf(data, "schannel: CertGetCertificateChain failed: %s", - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); pChainContext = NULL; result = CURLE_PEER_FAILED_VERIFICATION; } @@ -640,15 +640,15 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0]; DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED); dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus; - - if(data->set.ssl.revoke_best_effort) { - /* Ignore errors when root certificates are missing the revocation - * list URL, or when the list could not be downloaded because the - * server is currently unreachable. */ - dwTrustErrorMask &= ~(DWORD)(CERT_TRUST_REVOCATION_STATUS_UNKNOWN | - CERT_TRUST_IS_OFFLINE_REVOCATION); - } - + + if(data->set.ssl.revoke_best_effort) { + /* Ignore errors when root certificates are missing the revocation + * list URL, or when the list could not be downloaded because the + * server is currently unreachable. */ + dwTrustErrorMask &= ~(DWORD)(CERT_TRUST_REVOCATION_STATUS_UNKNOWN | + CERT_TRUST_IS_OFFLINE_REVOCATION); + } + if(dwTrustErrorMask) { if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED) failf(data, "schannel: CertGetCertificateChain trust error" diff --git a/contrib/libs/curl/lib/vtls/sectransp.c b/contrib/libs/curl/lib/vtls/sectransp.c index 8ef60cb1f3..d2e6eabc33 100644 --- a/contrib/libs/curl/lib/vtls/sectransp.c +++ b/contrib/libs/curl/lib/vtls/sectransp.c @@ -6,11 +6,11 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>. - * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -79,7 +79,7 @@ /* These macros mean "the following code is present to allow runtime backward compatibility with at least this cat or earlier": (You set this at build-time using the compiler command line option - "-mmacosx-version-min.") */ + "-mmacosx-version-min.") */ #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 @@ -199,8 +199,8 @@ static OSStatus SocketRead(SSLConnectionRef connection, UInt8 *currData = (UInt8 *)data; /*int sock = *(int *)connection;*/ struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; - struct ssl_backend_data *backend = connssl->backend; - int sock = backend->ssl_sockfd; + struct ssl_backend_data *backend = connssl->backend; + int sock = backend->ssl_sockfd; OSStatus rtn = noErr; size_t bytesRead; ssize_t rrtn; @@ -229,7 +229,7 @@ static OSStatus SocketRead(SSLConnectionRef connection, break; case EAGAIN: rtn = errSSLWouldBlock; - backend->ssl_direction = false; + backend->ssl_direction = false; break; default: rtn = ioErr; @@ -260,8 +260,8 @@ static OSStatus SocketWrite(SSLConnectionRef connection, size_t bytesSent = 0; /*int sock = *(int *)connection;*/ struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; - struct ssl_backend_data *backend = connssl->backend; - int sock = backend->ssl_sockfd; + struct ssl_backend_data *backend = connssl->backend; + int sock = backend->ssl_sockfd; ssize_t length; size_t dataLen = *dataLength; const UInt8 *dataPtr = (UInt8 *)data; @@ -281,7 +281,7 @@ static OSStatus SocketWrite(SSLConnectionRef connection, theErr = errno; if(theErr == EAGAIN) { ortn = errSSLWouldBlock; - backend->ssl_direction = true; + backend->ssl_direction = true; } else { ortn = ioErr; @@ -1126,12 +1126,12 @@ static OSStatus CopyIdentityWithLabel(char *label, } static OSStatus CopyIdentityFromPKCS12File(const char *cPath, - const struct curl_blob *blob, + const struct curl_blob *blob, const char *cPassword, SecIdentityRef *out_cert_and_key) { OSStatus status = errSecItemNotFound; - CFURLRef pkcs_url = NULL; + CFURLRef pkcs_url = NULL; CFStringRef password = cPassword ? CFStringCreateWithCString(NULL, cPassword, kCFStringEncodingUTF8) : NULL; CFDataRef pkcs_data = NULL; @@ -1140,26 +1140,26 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath, /* These constants are documented as having first appeared in 10.6 but they raise linker errors when used on that cat for some reason. */ #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS - bool resource_imported; - - if(blob) { - pkcs_data = CFDataCreate(kCFAllocatorDefault, - (const unsigned char *)blob->data, blob->len); - status = (pkcs_data != NULL) ? errSecSuccess : errSecAllocate; - resource_imported = (pkcs_data != NULL); - } - else { - pkcs_url = - CFURLCreateFromFileSystemRepresentation(NULL, - (const UInt8 *)cPath, - strlen(cPath), false); - resource_imported = - CFURLCreateDataAndPropertiesFromResource(NULL, - pkcs_url, &pkcs_data, - NULL, NULL, &status); - } - - if(resource_imported) { + bool resource_imported; + + if(blob) { + pkcs_data = CFDataCreate(kCFAllocatorDefault, + (const unsigned char *)blob->data, blob->len); + status = (pkcs_data != NULL) ? errSecSuccess : errSecAllocate; + resource_imported = (pkcs_data != NULL); + } + else { + pkcs_url = + CFURLCreateFromFileSystemRepresentation(NULL, + (const UInt8 *)cPath, + strlen(cPath), false); + resource_imported = + CFURLCreateDataAndPropertiesFromResource(NULL, + pkcs_url, &pkcs_data, + NULL, NULL, &status); + } + + if(resource_imported) { CFArrayRef items = NULL; /* On iOS SecPKCS12Import will never add the client certificate to the @@ -1182,7 +1182,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath, * the Keychain. * * As this doesn't match iOS, and apps may not want to see their client - * certificate saved in the user's keychain, we use SecItemImport + * certificate saved in the user's keychain, we use SecItemImport * with a NULL keychain to avoid importing it. * * This returns a SecCertificateRef from which we can construct a @@ -1237,8 +1237,8 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath, #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ if(password) CFRelease(password); - if(pkcs_url) - CFRelease(pkcs_url); + if(pkcs_url) + CFRelease(pkcs_url); return status; } @@ -1295,7 +1295,7 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex) { struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; long ssl_version = SSL_CONN_CONFIG(version); long ssl_version_max = SSL_CONN_CONFIG(version_max); long max_supported_version_by_os; @@ -1346,30 +1346,30 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex) return result; } - (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min); - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max); + (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min); + (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max); return result; } else { #if CURL_SUPPORT_MAC_10_8 long i = ssl_version; - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false); for(; i <= (ssl_version_max >> 16); i++) { switch(i) { case CURL_SSLVERSION_TLSv1_0: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kTLSProtocol1, true); break; case CURL_SSLVERSION_TLSv1_1: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kTLSProtocol11, true); break; case CURL_SSLVERSION_TLSv1_2: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kTLSProtocol12, true); break; @@ -1393,20 +1393,20 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, struct Curl_easy *data = conn->data; curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); - const struct curl_blob *ssl_cablob = NULL; + const struct curl_blob *ssl_cablob = NULL; const bool verifypeer = SSL_CONN_CONFIG(verifypeer); - char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); - const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); -#ifndef CURL_DISABLE_PROXY + char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); + const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); +#ifndef CURL_DISABLE_PROXY const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const char * const hostname = conn->host.name; - const long int port = conn->remote_port; -#endif +#else + const char * const hostname = conn->host.name; + const long int port = conn->remote_port; +#endif #ifdef ENABLE_IPV6 struct in6_addr addr; #else @@ -1423,10 +1423,10 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS if(SSLCreateContext != NULL) { /* use the newer API if available */ - if(backend->ssl_ctx) - CFRelease(backend->ssl_ctx); - backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); - if(!backend->ssl_ctx) { + if(backend->ssl_ctx) + CFRelease(backend->ssl_ctx); + backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); + if(!backend->ssl_ctx) { failf(data, "SSL: couldn't create a context!"); return CURLE_OUT_OF_MEMORY; } @@ -1434,9 +1434,9 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, else { /* The old ST API does not exist under iOS, so don't compile it: */ #if CURL_SUPPORT_MAC_10_8 - if(backend->ssl_ctx) - (void)SSLDisposeContext(backend->ssl_ctx); - err = SSLNewContext(false, &(backend->ssl_ctx)); + if(backend->ssl_ctx) + (void)SSLDisposeContext(backend->ssl_ctx); + err = SSLNewContext(false, &(backend->ssl_ctx)); if(err != noErr) { failf(data, "SSL: couldn't create a context: OSStatus %d", err); return CURLE_OUT_OF_MEMORY; @@ -1444,31 +1444,31 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, #endif /* CURL_SUPPORT_MAC_10_8 */ } #else - if(backend->ssl_ctx) - (void)SSLDisposeContext(backend->ssl_ctx); - err = SSLNewContext(false, &(backend->ssl_ctx)); + if(backend->ssl_ctx) + (void)SSLDisposeContext(backend->ssl_ctx); + err = SSLNewContext(false, &(backend->ssl_ctx)); if(err != noErr) { failf(data, "SSL: couldn't create a context: OSStatus %d", err); return CURLE_OUT_OF_MEMORY; } #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */ + backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */ /* check to see if we've been told to use an explicit SSL/TLS version */ #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS if(SSLSetProtocolVersionMax != NULL) { switch(conn->ssl_config.version) { case CURL_SSLVERSION_TLSv1: - (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1); + (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1); #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 if(__builtin_available(macOS 10.13, iOS 11.0, *)) { - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13); + (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13); } else { - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); + (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); } #else - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); + (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); #endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 */ break; @@ -1484,20 +1484,20 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, break; } case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol3); + err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol3); if(err != noErr) { failf(data, "Your version of the OS does not support SSLv3"); return CURLE_SSL_CONNECT_ERROR; } - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol3); + (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol3); break; case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol2); + err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol2); if(err != noErr) { failf(data, "Your version of the OS does not support SSLv2"); return CURLE_SSL_CONNECT_ERROR; } - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol2); + (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol2); break; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); @@ -1506,19 +1506,19 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, } else { #if CURL_SUPPORT_MAC_10_8 - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false); switch(conn->ssl_config.version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kTLSProtocol1, true); - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kTLSProtocol11, true); - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kTLSProtocol12, true); break; @@ -1533,7 +1533,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, break; } case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, + err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocol3, true); if(err != noErr) { @@ -1542,7 +1542,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, } break; case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, + err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocol2, true); if(err != noErr) { @@ -1562,12 +1562,12 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, " SSL/TLS version"); return CURLE_SSL_CONNECT_ERROR; } - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false); + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false); switch(conn->ssl_config.version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: case CURL_SSLVERSION_TLSv1_0: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, + (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kTLSProtocol1, true); break; @@ -1581,7 +1581,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, failf(data, "Your version of the OS does not support TLSv1.3"); return CURLE_SSL_CONNECT_ERROR; case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, + err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocol2, true); if(err != noErr) { @@ -1590,7 +1590,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, } break; case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, + err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocol3, true); if(err != noErr) { @@ -1611,11 +1611,11 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, &kCFTypeArrayCallBacks); #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 -#ifndef CURL_DISABLE_PROXY - && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) -#endif - ) { + if(data->set.httpversion >= CURL_HTTP_VERSION_2 +#ifndef CURL_DISABLE_PROXY + && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) +#endif + ) { CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID)); infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); } @@ -1627,7 +1627,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, /* expects length prefixed preference ordered list of protocols in wire * format */ - err = SSLSetALPNProtocols(backend->ssl_ctx, alpnArr); + err = SSLSetALPNProtocols(backend->ssl_ctx, alpnArr); if(err != noErr) infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n", err); @@ -1641,16 +1641,16 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, "Transport. The private key must be in the Keychain.\n"); } - if(ssl_cert || ssl_cert_blob) { - bool is_cert_data = ssl_cert_blob != NULL; - bool is_cert_file = (!is_cert_data) && is_file(ssl_cert); + if(ssl_cert || ssl_cert_blob) { + bool is_cert_data = ssl_cert_blob != NULL; + bool is_cert_file = (!is_cert_data) && is_file(ssl_cert); SecIdentityRef cert_and_key = NULL; /* User wants to authenticate with a client cert. Look for it: If we detect that this is a file on disk, then let's load it. Otherwise, assume that the user wants to use an identity loaded from the Keychain. */ - if(is_cert_file || is_cert_data) { + if(is_cert_file || is_cert_data) { if(!SSL_SET_OPTION(cert_type)) infof(data, "WARNING: SSL: Certificate type not set, assuming " "PKCS#12 format.\n"); @@ -1659,7 +1659,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, infof(data, "WARNING: SSL: The Security framework only supports " "loading identities that are in PKCS#12 format.\n"); - err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob, + err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob, SSL_SET_OPTION(key_passwd), &cert_and_key); } else @@ -1689,7 +1689,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, certs_c[0] = cert_and_key; certs = CFArrayCreate(NULL, (const void **)certs_c, 1L, &kCFTypeArrayCallBacks); - err = SSLSetCertificate(backend->ssl_ctx, certs); + err = SSLSetCertificate(backend->ssl_ctx, certs); if(certs) CFRelease(certs); if(err != noErr) { @@ -1699,30 +1699,30 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, CFRelease(cert_and_key); } else { - const char *cert_showfilename_error = - is_cert_data ? "(memory blob)" : ssl_cert; - + const char *cert_showfilename_error = + is_cert_data ? "(memory blob)" : ssl_cert; + switch(err) { case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */ failf(data, "SSL: Incorrect password for the certificate \"%s\" " - "and its private key.", cert_showfilename_error); + "and its private key.", cert_showfilename_error); break; case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */ failf(data, "SSL: Couldn't make sense of the data in the " "certificate \"%s\" and its private key.", - cert_showfilename_error); + cert_showfilename_error); break; case -25260: /* errSecPassphraseRequired */ failf(data, "SSL The certificate \"%s\" requires a password.", - cert_showfilename_error); + cert_showfilename_error); break; case errSecItemNotFound: failf(data, "SSL: Can't find the certificate \"%s\" and its private " - "key in the Keychain.", cert_showfilename_error); + "key in the Keychain.", cert_showfilename_error); break; default: failf(data, "SSL: Can't load the certificate \"%s\" and its private " - "key: OSStatus %d", cert_showfilename_error, err); + "key: OSStatus %d", cert_showfilename_error, err); break; } return CURLE_SSL_CERTPROBLEM; @@ -1754,9 +1754,9 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, #else if(SSLSetSessionOption != NULL) { #endif /* CURL_BUILD_MAC */ - bool break_on_auth = !conn->ssl_config.verifypeer || - ssl_cafile || ssl_cablob; - err = SSLSetSessionOption(backend->ssl_ctx, + bool break_on_auth = !conn->ssl_config.verifypeer || + ssl_cafile || ssl_cablob; + err = SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionBreakOnServerAuth, break_on_auth); if(err != noErr) { @@ -1766,7 +1766,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, } else { #if CURL_SUPPORT_MAC_10_8 - err = SSLSetEnableCertVerify(backend->ssl_ctx, + err = SSLSetEnableCertVerify(backend->ssl_ctx, conn->ssl_config.verifypeer?true:false); if(err != noErr) { failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); @@ -1775,7 +1775,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, #endif /* CURL_SUPPORT_MAC_10_8 */ } #else - err = SSLSetEnableCertVerify(backend->ssl_ctx, + err = SSLSetEnableCertVerify(backend->ssl_ctx, conn->ssl_config.verifypeer?true:false); if(err != noErr) { failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); @@ -1783,11 +1783,11 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, } #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ - if((ssl_cafile || ssl_cablob) && verifypeer) { - bool is_cert_data = ssl_cablob != NULL; - bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile); + if((ssl_cafile || ssl_cablob) && verifypeer) { + bool is_cert_data = ssl_cablob != NULL; + bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile); - if(!(is_cert_file || is_cert_data)) { + if(!(is_cert_file || is_cert_data)) { failf(data, "SSL: can't load CA certificate file %s", ssl_cafile); return CURLE_SSL_CACERT_BADFILE; } @@ -1797,7 +1797,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, * Both hostname check and SNI require SSLSetPeerDomainName(). * Also: the verifyhost setting influences SNI usage */ if(conn->ssl_config.verifyhost) { - err = SSLSetPeerDomainName(backend->ssl_ctx, hostname, + err = SSLSetPeerDomainName(backend->ssl_ctx, hostname, strlen(hostname)); if(err != noErr) { @@ -1823,7 +1823,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, higher priority, but it's probably better that we not connect at all than to give the user a false sense of security if the server only supports insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */ - err = SSLGetNumberSupportedCiphers(backend->ssl_ctx, &all_ciphers_count); + err = SSLGetNumberSupportedCiphers(backend->ssl_ctx, &all_ciphers_count); if(err != noErr) { failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d", err); @@ -1840,7 +1840,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, failf(data, "SSL: Failed to allocate memory for allowed ciphers"); return CURLE_OUT_OF_MEMORY; } - err = SSLGetSupportedCiphers(backend->ssl_ctx, all_ciphers, + err = SSLGetSupportedCiphers(backend->ssl_ctx, all_ciphers, &all_ciphers_count); if(err != noErr) { Curl_safefree(all_ciphers); @@ -1927,7 +1927,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, break; } } - err = SSLSetEnabledCiphers(backend->ssl_ctx, allowed_ciphers, + err = SSLSetEnabledCiphers(backend->ssl_ctx, allowed_ciphers, allowed_ciphers_count); Curl_safefree(all_ciphers); Curl_safefree(allowed_ciphers); @@ -1940,9 +1940,9 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, /* 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) { - SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord, + SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord, !data->set.ssl.enable_beast); - SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart, + SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart, data->set.ssl.falsestart); /* false start support */ } #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ @@ -1956,7 +1956,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid, &ssl_sessionid_len, sockindex)) { /* we got a session id, use it! */ - err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len); + err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len); Curl_ssl_sessionid_unlock(conn); if(err != noErr) { failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); @@ -1970,11 +1970,11 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, else { CURLcode result; ssl_sessionid = - aprintf("%s:%d:%d:%s:%ld", ssl_cafile, + aprintf("%s:%d:%d:%s:%ld", ssl_cafile, verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port); ssl_sessionid_len = strlen(ssl_sessionid); - err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len); + err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len); if(err != noErr) { Curl_ssl_sessionid_unlock(conn); failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); @@ -1991,7 +1991,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, } } - err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite); + err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite); if(err != noErr) { failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err); return CURLE_SSL_CONNECT_ERROR; @@ -2001,8 +2001,8 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn, /* We need to store the FD in a constant memory address, because * SSLSetConnection() will not copy that address. I've found that * conn->sock[sockindex] may change on its own. */ - backend->ssl_sockfd = sockfd; - err = SSLSetConnection(backend->ssl_ctx, connssl); + backend->ssl_sockfd = sockfd; + err = SSLSetConnection(backend->ssl_ctx, connssl); if(err != noErr) { failf(data, "SSL: SSLSetConnection() failed: %d", err); return CURLE_SSL_CONNECT_ERROR; @@ -2189,7 +2189,7 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, if(res < 0) { free(certbuf); CFRelease(array); - failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle", + failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle", n, offset); return CURLE_SSL_CACERT_BADFILE; } @@ -2383,28 +2383,28 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex) { struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; OSStatus err; SSLCipherSuite cipher; SSLProtocol protocol = 0; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; -#else - const char * const hostname = conn->host.name; -#endif +#else + const char * const hostname = conn->host.name; +#endif DEBUGASSERT(ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state || ssl_connect_2_writing == connssl->connecting_state); /* Here goes nothing: */ - err = SSLHandshake(backend->ssl_ctx); + err = SSLHandshake(backend->ssl_ctx); if(err != noErr) { switch(err) { case errSSLWouldBlock: /* they're not done with us yet */ - connssl->connecting_state = backend->ssl_direction ? + connssl->connecting_state = backend->ssl_direction ? ssl_connect_2_writing : ssl_connect_2_reading; return CURLE_OK; @@ -2413,7 +2413,7 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex) case -9841: if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data, - backend->ssl_ctx); + backend->ssl_ctx); if(result) return result; } @@ -2622,7 +2622,7 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex) #ifdef SECTRANSP_PINNEDPUBKEY if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) { - CURLcode result = pkp_pin_peer_pubkey(data, backend->ssl_ctx, + CURLcode result = pkp_pin_peer_pubkey(data, backend->ssl_ctx, data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]); if(result) { failf(data, "SSL: public key does not match pinned public key!"); @@ -2632,8 +2632,8 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex) #endif /* SECTRANSP_PINNEDPUBKEY */ /* Informational message */ - (void)SSLGetNegotiatedCipher(backend->ssl_ctx, &cipher); - (void)SSLGetNegotiatedProtocolVersion(backend->ssl_ctx, &protocol); + (void)SSLGetNegotiatedCipher(backend->ssl_ctx, &cipher); + (void)SSLGetNegotiatedProtocolVersion(backend->ssl_ctx, &protocol); switch(protocol) { case kSSLProtocol2: infof(data, "SSL 2.0 connection using %s\n", @@ -2673,7 +2673,7 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex) if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) { CFArrayRef alpnArr = NULL; CFStringRef chosenProtocol = NULL; - err = SSLCopyALPNProtocols(backend->ssl_ctx, &alpnArr); + err = SSLCopyALPNProtocols(backend->ssl_ctx, &alpnArr); if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1) chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0); @@ -2716,20 +2716,20 @@ show_verbose_server_cert(struct connectdata *conn, { struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; CFArrayRef server_certs = NULL; SecCertificateRef server_cert; OSStatus err; CFIndex i, count; SecTrustRef trust = NULL; - if(!backend->ssl_ctx) + if(!backend->ssl_ctx) return; #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS #if CURL_BUILD_IOS #pragma unused(server_certs) - err = SSLCopyPeerTrust(backend->ssl_ctx, &trust); + err = SSLCopyPeerTrust(backend->ssl_ctx, &trust); /* For some reason, SSLCopyPeerTrust() can return noErr and yet return a null trust, so be on guard for that: */ if(err == noErr && trust) { @@ -2755,7 +2755,7 @@ show_verbose_server_cert(struct connectdata *conn, Lion or later. */ if(SecTrustEvaluateAsync != NULL) { #pragma unused(server_certs) - err = SSLCopyPeerTrust(backend->ssl_ctx, &trust); + err = SSLCopyPeerTrust(backend->ssl_ctx, &trust); /* For some reason, SSLCopyPeerTrust() can return noErr and yet return a null trust, so be on guard for that: */ if(err == noErr && trust) { @@ -2775,7 +2775,7 @@ show_verbose_server_cert(struct connectdata *conn, } else { #if CURL_SUPPORT_MAC_10_8 - err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs); + err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs); /* Just in case SSLCopyPeerCertificates() returns null too... */ if(err == noErr && server_certs) { count = CFArrayGetCount(server_certs); @@ -2797,7 +2797,7 @@ show_verbose_server_cert(struct connectdata *conn, #endif /* CURL_BUILD_IOS */ #else #pragma unused(trust) - err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs); + err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs); if(err == noErr) { count = CFArrayGetCount(server_certs); for(i = 0L ; i < count ; i++) { @@ -2858,7 +2858,7 @@ sectransp_connect_common(struct connectdata *conn, if(ssl_connect_1 == connssl->connecting_state) { /* Find out how much more time we're allowed */ - const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); if(timeout_ms < 0) { /* no need to continue if time already is up */ @@ -2876,7 +2876,7 @@ sectransp_connect_common(struct connectdata *conn, ssl_connect_2_writing == connssl->connecting_state) { /* check allowed time left */ - const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); if(timeout_ms < 0) { /* no need to continue if time already is up */ @@ -2894,7 +2894,7 @@ sectransp_connect_common(struct connectdata *conn, connssl->connecting_state?sockfd:CURL_SOCKET_BAD; what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, - nonblocking ? 0 : timeout_ms); + nonblocking ? 0 : timeout_ms); if(what < 0) { /* fatal error */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); @@ -2975,36 +2975,36 @@ static CURLcode Curl_sectransp_connect(struct connectdata *conn, int sockindex) static void Curl_sectransp_close(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; - if(backend->ssl_ctx) { - (void)SSLClose(backend->ssl_ctx); + if(backend->ssl_ctx) { + (void)SSLClose(backend->ssl_ctx); #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS if(SSLCreateContext != NULL) - CFRelease(backend->ssl_ctx); + CFRelease(backend->ssl_ctx); #if CURL_SUPPORT_MAC_10_8 else - (void)SSLDisposeContext(backend->ssl_ctx); + (void)SSLDisposeContext(backend->ssl_ctx); #endif /* CURL_SUPPORT_MAC_10_8 */ #else - (void)SSLDisposeContext(backend->ssl_ctx); + (void)SSLDisposeContext(backend->ssl_ctx); #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - backend->ssl_ctx = NULL; + backend->ssl_ctx = NULL; } - backend->ssl_sockfd = 0; + backend->ssl_sockfd = 0; } static int Curl_sectransp_shutdown(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; struct Curl_easy *data = conn->data; ssize_t nread; int what; int rc; char buf[120]; - if(!backend->ssl_ctx) + if(!backend->ssl_ctx) return 0; #ifndef CURL_DISABLE_FTP @@ -3077,12 +3077,12 @@ static size_t Curl_sectransp_version(char *buffer, size_t size) static int Curl_sectransp_check_cxn(struct connectdata *conn) { struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; OSStatus err; SSLSessionState state; - if(backend->ssl_ctx) { - err = SSLGetSessionState(backend->ssl_ctx, &state); + if(backend->ssl_ctx) { + err = SSLGetSessionState(backend->ssl_ctx, &state); if(err == noErr) return state == kSSLConnected || state == kSSLHandshake; return -1; @@ -3094,12 +3094,12 @@ static bool Curl_sectransp_data_pending(const struct connectdata *conn, int connindex) { const struct ssl_connect_data *connssl = &conn->ssl[connindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; OSStatus err; size_t buffer; - if(backend->ssl_ctx) { /* SSL is in use */ - err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer); + if(backend->ssl_ctx) { /* SSL is in use */ + err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer); if(err == noErr) return buffer > 0UL; return false; @@ -3165,7 +3165,7 @@ static ssize_t sectransp_send(struct connectdata *conn, { /*struct Curl_easy *data = conn->data;*/ struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; size_t processed = 0UL; OSStatus err; @@ -3184,15 +3184,15 @@ static ssize_t sectransp_send(struct connectdata *conn, over again with no new data until it quits returning errSSLWouldBlock. */ /* Do we have buffered data to write from the last time we were called? */ - if(backend->ssl_write_buffered_length) { + if(backend->ssl_write_buffered_length) { /* Write the buffered data: */ - err = SSLWrite(backend->ssl_ctx, NULL, 0UL, &processed); + err = SSLWrite(backend->ssl_ctx, NULL, 0UL, &processed); switch(err) { case noErr: /* processed is always going to be 0 because we didn't write to the buffer, so return how much was written to the socket */ - processed = backend->ssl_write_buffered_length; - backend->ssl_write_buffered_length = 0UL; + processed = backend->ssl_write_buffered_length; + backend->ssl_write_buffered_length = 0UL; break; case errSSLWouldBlock: /* argh, try again */ *curlcode = CURLE_AGAIN; @@ -3205,13 +3205,13 @@ static ssize_t sectransp_send(struct connectdata *conn, } else { /* We've got new data to write: */ - err = SSLWrite(backend->ssl_ctx, mem, len, &processed); + err = SSLWrite(backend->ssl_ctx, mem, len, &processed); if(err != noErr) { switch(err) { case errSSLWouldBlock: /* Data was buffered but not sent, we have to tell the caller to try sending again, and remember how much was buffered */ - backend->ssl_write_buffered_length = len; + backend->ssl_write_buffered_length = len; *curlcode = CURLE_AGAIN; return -1L; default: @@ -3232,12 +3232,12 @@ static ssize_t sectransp_recv(struct connectdata *conn, { /*struct Curl_easy *data = conn->data;*/ struct ssl_connect_data *connssl = &conn->ssl[num]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; size_t processed = 0UL; OSStatus err; again: - err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed); + err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed); if(err != noErr) { switch(err) { @@ -3263,7 +3263,7 @@ static ssize_t sectransp_recv(struct connectdata *conn, case -9841: if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), conn->data, - backend->ssl_ctx); + backend->ssl_ctx); if(result) return result; } @@ -3281,9 +3281,9 @@ static ssize_t sectransp_recv(struct connectdata *conn, static void *Curl_sectransp_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) { - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; (void)info; - return backend->ssl_ctx; + return backend->ssl_ctx; } const struct Curl_ssl Curl_ssl_sectransp = { diff --git a/contrib/libs/curl/lib/vtls/sectransp.h b/contrib/libs/curl/lib/vtls/sectransp.h index 0febd6613a..6b85a367da 100644 --- a/contrib/libs/curl/lib/vtls/sectransp.h +++ b/contrib/libs/curl/lib/vtls/sectransp.h @@ -8,11 +8,11 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>. - * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is diff --git a/contrib/libs/curl/lib/vtls/vtls.c b/contrib/libs/curl/lib/vtls/vtls.c index 3bd51fdaf2..5da28209a9 100644 --- a/contrib/libs/curl/lib/vtls/vtls.c +++ b/contrib/libs/curl/lib/vtls/vtls.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -63,7 +63,7 @@ #include "warnless.h" #include "curl_base64.h" #include "curl_printf.h" -#include "strdup.h" +#include "strdup.h" /* The last #include files should be: */ #include "curl_memory.h" @@ -83,63 +83,63 @@ else \ dest->var = NULL; -#define CLONE_BLOB(var) \ - if(blobdup(&dest->var, source->var)) \ - return FALSE; - -static CURLcode blobdup(struct curl_blob **dest, - struct curl_blob *src) -{ - DEBUGASSERT(dest); - DEBUGASSERT(!*dest); - if(src) { - /* only if there's data to dupe! */ - struct curl_blob *d; - d = malloc(sizeof(struct curl_blob) + src->len); - if(!d) - return CURLE_OUT_OF_MEMORY; - d->len = src->len; - /* Always duplicate because the connection may survive longer than the - handle that passed in the blob. */ - d->flags = CURL_BLOB_COPY; - d->data = (void *)((char *)d + sizeof(struct curl_blob)); - memcpy(d->data, src->data, src->len); - *dest = d; - } - return CURLE_OK; -} - -/* returns TRUE if the blobs are identical */ -static bool blobcmp(struct curl_blob *first, struct curl_blob *second) -{ - if(!first && !second) /* both are NULL */ - return TRUE; - if(!first || !second) /* one is NULL */ - return FALSE; - if(first->len != second->len) /* different sizes */ - return FALSE; - return !memcmp(first->data, second->data, first->len); /* same data */ -} - +#define CLONE_BLOB(var) \ + if(blobdup(&dest->var, source->var)) \ + return FALSE; + +static CURLcode blobdup(struct curl_blob **dest, + struct curl_blob *src) +{ + DEBUGASSERT(dest); + DEBUGASSERT(!*dest); + if(src) { + /* only if there's data to dupe! */ + struct curl_blob *d; + d = malloc(sizeof(struct curl_blob) + src->len); + if(!d) + return CURLE_OUT_OF_MEMORY; + d->len = src->len; + /* Always duplicate because the connection may survive longer than the + handle that passed in the blob. */ + d->flags = CURL_BLOB_COPY; + d->data = (void *)((char *)d + sizeof(struct curl_blob)); + memcpy(d->data, src->data, src->len); + *dest = d; + } + return CURLE_OK; +} + +/* returns TRUE if the blobs are identical */ +static bool blobcmp(struct curl_blob *first, struct curl_blob *second) +{ + if(!first && !second) /* both are NULL */ + return TRUE; + if(!first || !second) /* one is NULL */ + return FALSE; + if(first->len != second->len) /* different sizes */ + return FALSE; + return !memcmp(first->data, second->data, first->len); /* same data */ +} + bool -Curl_ssl_config_matches(struct ssl_primary_config *data, - struct ssl_primary_config *needle) +Curl_ssl_config_matches(struct ssl_primary_config *data, + struct ssl_primary_config *needle) { if((data->version == needle->version) && (data->version_max == needle->version_max) && (data->verifypeer == needle->verifypeer) && (data->verifyhost == needle->verifyhost) && (data->verifystatus == needle->verifystatus) && - blobcmp(data->cert_blob, needle->cert_blob) && + blobcmp(data->cert_blob, needle->cert_blob) && Curl_safe_strcasecompare(data->CApath, needle->CApath) && Curl_safe_strcasecompare(data->CAfile, needle->CAfile) && Curl_safe_strcasecompare(data->clientcert, needle->clientcert) && Curl_safe_strcasecompare(data->random_file, needle->random_file) && Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) && Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && - Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) && - Curl_safe_strcasecompare(data->curves, needle->curves) && - Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key)) + Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) && + Curl_safe_strcasecompare(data->curves, needle->curves) && + Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key)) return TRUE; return FALSE; @@ -156,7 +156,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, dest->verifystatus = source->verifystatus; dest->sessionid = source->sessionid; - CLONE_BLOB(cert_blob); + CLONE_BLOB(cert_blob); CLONE_STRING(CApath); CLONE_STRING(CAfile); CLONE_STRING(clientcert); @@ -164,13 +164,13 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, CLONE_STRING(egdsocket); CLONE_STRING(cipher_list); CLONE_STRING(cipher_list13); - CLONE_STRING(pinned_key); - CLONE_STRING(curves); + CLONE_STRING(pinned_key); + CLONE_STRING(curves); return TRUE; } -void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) +void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) { Curl_safefree(sslc->CApath); Curl_safefree(sslc->CAfile); @@ -179,9 +179,9 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) Curl_safefree(sslc->egdsocket); Curl_safefree(sslc->cipher_list); Curl_safefree(sslc->cipher_list13); - Curl_safefree(sslc->pinned_key); - Curl_safefree(sslc->cert_blob); - Curl_safefree(sslc->curves); + Curl_safefree(sslc->pinned_key); + Curl_safefree(sslc->cert_blob); + Curl_safefree(sslc->curves); } #ifdef USE_SSL @@ -219,9 +219,9 @@ int Curl_ssl_init(void) return Curl_ssl->init(); } -#if defined(CURL_WITH_MULTI_SSL) -static const struct Curl_ssl Curl_ssl_multi; -#endif +#if defined(CURL_WITH_MULTI_SSL) +static const struct Curl_ssl Curl_ssl_multi; +#endif /* Global cleanup */ void Curl_ssl_cleanup(void) @@ -229,9 +229,9 @@ void Curl_ssl_cleanup(void) if(init_ssl) { /* only cleanup if we did a previous init */ Curl_ssl->cleanup(); -#if defined(CURL_WITH_MULTI_SSL) - Curl_ssl = &Curl_ssl_multi; -#endif +#if defined(CURL_WITH_MULTI_SSL) + Curl_ssl = &Curl_ssl_multi; +#endif init_ssl = FALSE; } } @@ -260,7 +260,7 @@ static bool ssl_prefs_check(struct Curl_easy *data) return TRUE; } -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY static CURLcode ssl_connect_init_proxy(struct connectdata *conn, int sockindex) { @@ -284,20 +284,20 @@ ssl_connect_init_proxy(struct connectdata *conn, int sockindex) } return CURLE_OK; } -#endif +#endif CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex) { CURLcode result; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY if(conn->bits.proxy_ssl_connected[sockindex]) { result = ssl_connect_init_proxy(conn, sockindex); if(result) return result; } -#endif +#endif if(!ssl_prefs_check(conn->data)) return CURLE_SSL_CONNECT_ERROR; @@ -319,13 +319,13 @@ Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex, bool *done) { CURLcode result; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY if(conn->bits.proxy_ssl_connected[sockindex]) { result = ssl_connect_init_proxy(conn, sockindex); if(result) return result; } -#endif +#endif if(!ssl_prefs_check(conn->data)) return CURLE_SSL_CONNECT_ERROR; @@ -365,27 +365,27 @@ bool Curl_ssl_getsessionid(struct connectdata *conn, size_t *idsize, /* set 0 if unknown */ int sockindex) { - struct Curl_ssl_session *check; + struct Curl_ssl_session *check; struct Curl_easy *data = conn->data; size_t i; long *general_age; bool no_match = TRUE; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY const bool isProxy = CONNECT_PROXY_SSL(); struct ssl_primary_config * const ssl_config = isProxy ? &conn->proxy_ssl_config : &conn->ssl_config; - const char * const name = isProxy ? - conn->http_proxy.host.name : conn->host.name; + const char * const name = isProxy ? + conn->http_proxy.host.name : conn->host.name; int port = isProxy ? (int)conn->port : conn->remote_port; -#else - /* no proxy support */ - struct ssl_primary_config * const ssl_config = &conn->ssl_config; - const char * const name = conn->host.name; - int port = conn->remote_port; - (void)sockindex; -#endif +#else + /* no proxy support */ + struct ssl_primary_config * const ssl_config = &conn->ssl_config; + const char * const name = conn->host.name; + int port = conn->remote_port; + (void)sockindex; +#endif *ssl_sessionid = NULL; DEBUGASSERT(SSL_SET_OPTION(primary.sessionid)); @@ -432,7 +432,7 @@ bool Curl_ssl_getsessionid(struct connectdata *conn, /* * Kill a single session ID entry in the cache. */ -void Curl_ssl_kill_session(struct Curl_ssl_session *session) +void Curl_ssl_kill_session(struct Curl_ssl_session *session) { if(session->sessionid) { /* defensive check */ @@ -459,7 +459,7 @@ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid) struct Curl_easy *data = conn->data; for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) { - struct Curl_ssl_session *check = &data->state.session[i]; + struct Curl_ssl_session *check = &data->state.session[i]; if(check->sessionid == ssl_sessionid) { Curl_ssl_kill_session(check); @@ -481,29 +481,29 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, { size_t i; struct Curl_easy *data = conn->data; /* the mother of all structs */ - struct Curl_ssl_session *store = &data->state.session[0]; + struct Curl_ssl_session *store = &data->state.session[0]; long oldest_age = data->state.session[0].age; /* zero if unused */ char *clone_host; char *clone_conn_to_host; int conn_to_port; long *general_age; -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY const bool isProxy = CONNECT_PROXY_SSL(); struct ssl_primary_config * const ssl_config = isProxy ? &conn->proxy_ssl_config : &conn->ssl_config; - const char *hostname = isProxy ? conn->http_proxy.host.name : - conn->host.name; -#else - /* proxy support disabled */ - const bool isProxy = FALSE; - struct ssl_primary_config * const ssl_config = &conn->ssl_config; - const char *hostname = conn->host.name; - (void)sockindex; -#endif + const char *hostname = isProxy ? conn->http_proxy.host.name : + conn->host.name; +#else + /* proxy support disabled */ + const bool isProxy = FALSE; + struct ssl_primary_config * const ssl_config = &conn->ssl_config; + const char *hostname = conn->host.name; + (void)sockindex; +#endif DEBUGASSERT(SSL_SET_OPTION(primary.sessionid)); - clone_host = strdup(hostname); + clone_host = strdup(hostname); if(!clone_host) return CURLE_OUT_OF_MEMORY; /* bail out */ @@ -562,7 +562,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, store->scheme = conn->handler->scheme; if(!Curl_clone_primary_ssl_config(ssl_config, &store->ssl_config)) { - Curl_free_primary_ssl_config(&store->ssl_config); + Curl_free_primary_ssl_config(&store->ssl_config); store->sessionid = NULL; /* let caller free sessionid */ free(clone_host); free(clone_conn_to_host); @@ -590,8 +590,8 @@ void Curl_ssl_close_all(struct Curl_easy *data) } #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ - defined(USE_SECTRANSP) || defined(USE_NSS) || \ - defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_BEARSSL) + defined(USE_SECTRANSP) || defined(USE_NSS) || \ + defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_BEARSSL) int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks) { struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; @@ -624,7 +624,7 @@ void Curl_ssl_close(struct connectdata *conn, int sockindex) { DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); Curl_ssl->close_one(conn, sockindex); - conn->ssl[sockindex].state = ssl_connection_none; + conn->ssl[sockindex].state = ssl_connection_none; } CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex) @@ -667,13 +667,13 @@ struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data) */ CURLcode Curl_ssl_initsessions(struct Curl_easy *data, size_t amount) { - struct Curl_ssl_session *session; + struct Curl_ssl_session *session; if(data->state.session) /* this is just a precaution to prevent multiple inits */ return CURLE_OK; - session = calloc(amount, sizeof(struct Curl_ssl_session)); + session = calloc(amount, sizeof(struct Curl_ssl_session)); if(!session) return CURLE_OUT_OF_MEMORY; @@ -752,7 +752,7 @@ CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num) } /* - * 'value' is NOT a null-terminated string + * 'value' is NOT a null-terminated string */ CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, int certnum, @@ -774,10 +774,10 @@ CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, /* sprintf the label and colon */ msnprintf(output, outlen, "%s:", label); - /* memcpy the value (it might not be null-terminated) */ + /* memcpy the value (it might not be null-terminated) */ memcpy(&output[labellen + 1], value, valuelen); - /* null-terminate the output */ + /* null-terminate the output */ output[labellen + 1 + valuelen] = 0; nl = Curl_slist_append_nodup(ci->certinfo[certnum], output); @@ -1152,7 +1152,7 @@ bool Curl_none_false_start(void) CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, unsigned char *md5sum, size_t md5len UNUSED_PARAM) { - struct MD5_context *MD5pw; + struct MD5_context *MD5pw; (void)md5len; @@ -1262,8 +1262,8 @@ const struct Curl_ssl *Curl_ssl = &Curl_ssl_schannel; #elif defined(USE_MESALINK) &Curl_ssl_mesalink; -#elif defined(USE_BEARSSL) - &Curl_ssl_bearssl; +#elif defined(USE_BEARSSL) + &Curl_ssl_bearssl; #else #error "Missing struct Curl_ssl for selected SSL backend" #endif @@ -1296,9 +1296,9 @@ static const struct Curl_ssl *available_backends[] = { #if defined(USE_MESALINK) &Curl_ssl_mesalink, #endif -#if defined(USE_BEARSSL) - &Curl_ssl_bearssl, -#endif +#if defined(USE_BEARSSL) + &Curl_ssl_bearssl, +#endif NULL }; @@ -1306,7 +1306,7 @@ static size_t Curl_multissl_version(char *buffer, size_t size) { static const struct Curl_ssl *selected; static char backends[200]; - static size_t backends_len; + static size_t backends_len; const struct Curl_ssl *current; current = Curl_ssl == &Curl_ssl_multi ? available_backends[0] : Curl_ssl; @@ -1318,32 +1318,32 @@ static size_t Curl_multissl_version(char *buffer, size_t size) selected = current; - backends[0] = '\0'; - - for(i = 0; available_backends[i]; ++i) { - char vb[200]; - bool paren = (selected != available_backends[i]); - - if(available_backends[i]->version(vb, sizeof(vb))) { - p += msnprintf(p, end - p, "%s%s%s%s", (p != backends ? " " : ""), - (paren ? "(" : ""), vb, (paren ? ")" : "")); - } + backends[0] = '\0'; + + for(i = 0; available_backends[i]; ++i) { + char vb[200]; + bool paren = (selected != available_backends[i]); + + if(available_backends[i]->version(vb, sizeof(vb))) { + p += msnprintf(p, end - p, "%s%s%s%s", (p != backends ? " " : ""), + (paren ? "(" : ""), vb, (paren ? ")" : "")); + } } - - backends_len = p - backends; + + backends_len = p - backends; } - if(!size) - return 0; - - if(size <= backends_len) { - strncpy(buffer, backends, size - 1); + if(!size) + return 0; + + if(size <= backends_len) { + strncpy(buffer, backends, size - 1); buffer[size - 1] = '\0'; - return size - 1; + return size - 1; } - strcpy(buffer, backends); - return backends_len; + strcpy(buffer, backends); + return backends_len; } static int multissl_init(const struct Curl_ssl *backend) diff --git a/contrib/libs/curl/lib/vtls/vtls.h b/contrib/libs/curl/lib/vtls/vtls.h index f4cab9988f..aeb1cb6537 100644 --- a/contrib/libs/curl/lib/vtls/vtls.h +++ b/contrib/libs/curl/lib/vtls/vtls.h @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -107,7 +107,7 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, #include "sectransp.h" /* SecureTransport (Darwin) version */ #include "mbedtls.h" /* mbedTLS versions */ #include "mesalink.h" /* MesaLink versions */ -#include "bearssl.h" /* BearSSL versions */ +#include "bearssl.h" /* BearSSL versions */ #ifndef MAX_PINNED_PUBKEY_SIZE #define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */ @@ -123,41 +123,41 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, /* set of helper macros for the backends to access the correct fields. For the proxy or for the remote host - to properly support HTTPS proxy */ -#ifndef CURL_DISABLE_PROXY -#define SSL_IS_PROXY() \ - (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \ - ssl_connection_complete != \ - conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \ - CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state) -#define SSL_SET_OPTION(var) \ - (SSL_IS_PROXY() ? data->set.proxy_ssl.var : data->set.ssl.var) -#define SSL_SET_OPTION_LVALUE(var) \ - (*(SSL_IS_PROXY() ? &data->set.proxy_ssl.var : &data->set.ssl.var)) -#define SSL_CONN_CONFIG(var) \ - (SSL_IS_PROXY() ? conn->proxy_ssl_config.var : conn->ssl_config.var) -#define SSL_HOST_NAME() \ - (SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name) -#define SSL_HOST_DISPNAME() \ - (SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname) -#define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \ - ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \ - : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) -#else -#define SSL_IS_PROXY() FALSE -#define SSL_SET_OPTION(var) data->set.ssl.var -#define SSL_SET_OPTION_LVALUE(var) data->set.ssl.var -#define SSL_CONN_CONFIG(var) conn->ssl_config.var -#define SSL_HOST_NAME() conn->host.name -#define SSL_HOST_DISPNAME() conn->host.dispname -#define SSL_PINNED_PUB_KEY() \ - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG] -#endif - -bool Curl_ssl_config_matches(struct ssl_primary_config *data, - struct ssl_primary_config *needle); +#ifndef CURL_DISABLE_PROXY +#define SSL_IS_PROXY() \ + (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \ + ssl_connection_complete != \ + conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \ + CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state) +#define SSL_SET_OPTION(var) \ + (SSL_IS_PROXY() ? data->set.proxy_ssl.var : data->set.ssl.var) +#define SSL_SET_OPTION_LVALUE(var) \ + (*(SSL_IS_PROXY() ? &data->set.proxy_ssl.var : &data->set.ssl.var)) +#define SSL_CONN_CONFIG(var) \ + (SSL_IS_PROXY() ? conn->proxy_ssl_config.var : conn->ssl_config.var) +#define SSL_HOST_NAME() \ + (SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name) +#define SSL_HOST_DISPNAME() \ + (SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname) +#define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \ + ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \ + : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) +#else +#define SSL_IS_PROXY() FALSE +#define SSL_SET_OPTION(var) data->set.ssl.var +#define SSL_SET_OPTION_LVALUE(var) data->set.ssl.var +#define SSL_CONN_CONFIG(var) conn->ssl_config.var +#define SSL_HOST_NAME() conn->host.name +#define SSL_HOST_DISPNAME() conn->host.dispname +#define SSL_PINNED_PUB_KEY() \ + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG] +#endif + +bool Curl_ssl_config_matches(struct ssl_primary_config *data, + struct ssl_primary_config *needle); bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source, struct ssl_primary_config *dest); -void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc); +void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc); int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks); int Curl_ssl_backend(void); @@ -235,7 +235,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, * take sessionid object ownership from sessionid cache * (e.g. decrement refcount). */ -void Curl_ssl_kill_session(struct Curl_ssl_session *session); +void Curl_ssl_kill_session(struct Curl_ssl_session *session); /* delete a session from the cache * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock). * This will call engine-specific curlssl_session_free function, which must diff --git a/contrib/libs/curl/lib/vtls/wolfssl.c b/contrib/libs/curl/lib/vtls/wolfssl.c index ac9818824d..8b37965f93 100644 --- a/contrib/libs/curl/lib/vtls/wolfssl.c +++ b/contrib/libs/curl/lib/vtls/wolfssl.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -63,7 +63,7 @@ #include "sendf.h" #include "inet_pton.h" #include "vtls.h" -#include "keylog.h" +#include "keylog.h" #include "parsedate.h" #include "connect.h" /* for the connect timeout */ #include "select.h" @@ -100,107 +100,107 @@ struct ssl_backend_data { static Curl_recv wolfssl_recv; static Curl_send wolfssl_send; -#ifdef OPENSSL_EXTRA -/* - * Availability note: - * The TLS 1.3 secret callback (wolfSSL_set_tls13_secret_cb) was added in - * WolfSSL 4.4.0, but requires the -DHAVE_SECRET_CALLBACK build option. If that - * option is not set, then TLS 1.3 will not be logged. - * For TLS 1.2 and before, we use wolfSSL_get_keys(). - * SSL_get_client_random and wolfSSL_get_keys require OPENSSL_EXTRA - * (--enable-opensslextra or --enable-all). - */ -#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) -static int -wolfssl_tls13_secret_callback(SSL *ssl, int id, const unsigned char *secret, - int secretSz, void *ctx) -{ - const char *label; - unsigned char client_random[SSL3_RANDOM_SIZE]; - (void)ctx; - - if(!ssl || !Curl_tls_keylog_enabled()) { - return 0; - } - - switch(id) { - case CLIENT_EARLY_TRAFFIC_SECRET: - label = "CLIENT_EARLY_TRAFFIC_SECRET"; - break; - case CLIENT_HANDSHAKE_TRAFFIC_SECRET: - label = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"; - break; - case SERVER_HANDSHAKE_TRAFFIC_SECRET: - label = "SERVER_HANDSHAKE_TRAFFIC_SECRET"; - break; - case CLIENT_TRAFFIC_SECRET: - label = "CLIENT_TRAFFIC_SECRET_0"; - break; - case SERVER_TRAFFIC_SECRET: - label = "SERVER_TRAFFIC_SECRET_0"; - break; - case EARLY_EXPORTER_SECRET: - label = "EARLY_EXPORTER_SECRET"; - break; - case EXPORTER_SECRET: - label = "EXPORTER_SECRET"; - break; - default: - return 0; - } - - if(SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE) == 0) { - /* Should never happen as wolfSSL_KeepArrays() was called before. */ - return 0; - } - - Curl_tls_keylog_write(label, client_random, secret, secretSz); - return 0; -} -#endif /* defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) */ - -static void -wolfssl_log_tls12_secret(SSL *ssl) -{ - unsigned char *ms, *sr, *cr; - unsigned int msLen, srLen, crLen, i, x = 0; - -#if LIBWOLFSSL_VERSION_HEX >= 0x0300d000 /* >= 3.13.0 */ - /* wolfSSL_GetVersion is available since 3.13, we use it instead of - * SSL_version since the latter relies on OPENSSL_ALL (--enable-opensslall or - * --enable-all). Failing to perform this check could result in an unusable - * key log line when TLS 1.3 is actually negotiated. */ - switch(wolfSSL_GetVersion(ssl)) { - case WOLFSSL_SSLV3: - case WOLFSSL_TLSV1: - case WOLFSSL_TLSV1_1: - case WOLFSSL_TLSV1_2: - break; - default: - /* TLS 1.3 does not use this mechanism, the "master secret" returned below - * is not directly usable. */ - return; - } -#endif - - if(SSL_get_keys(ssl, &ms, &msLen, &sr, &srLen, &cr, &crLen) != SSL_SUCCESS) { - return; - } - - /* Check for a missing master secret and skip logging. That can happen if - * curl rejects the server certificate and aborts the handshake. - */ - for(i = 0; i < msLen; i++) { - x |= ms[i]; - } - if(x == 0) { - return; - } - - Curl_tls_keylog_write("CLIENT_RANDOM", cr, ms, msLen); -} -#endif /* OPENSSL_EXTRA */ - +#ifdef OPENSSL_EXTRA +/* + * Availability note: + * The TLS 1.3 secret callback (wolfSSL_set_tls13_secret_cb) was added in + * WolfSSL 4.4.0, but requires the -DHAVE_SECRET_CALLBACK build option. If that + * option is not set, then TLS 1.3 will not be logged. + * For TLS 1.2 and before, we use wolfSSL_get_keys(). + * SSL_get_client_random and wolfSSL_get_keys require OPENSSL_EXTRA + * (--enable-opensslextra or --enable-all). + */ +#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) +static int +wolfssl_tls13_secret_callback(SSL *ssl, int id, const unsigned char *secret, + int secretSz, void *ctx) +{ + const char *label; + unsigned char client_random[SSL3_RANDOM_SIZE]; + (void)ctx; + + if(!ssl || !Curl_tls_keylog_enabled()) { + return 0; + } + + switch(id) { + case CLIENT_EARLY_TRAFFIC_SECRET: + label = "CLIENT_EARLY_TRAFFIC_SECRET"; + break; + case CLIENT_HANDSHAKE_TRAFFIC_SECRET: + label = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"; + break; + case SERVER_HANDSHAKE_TRAFFIC_SECRET: + label = "SERVER_HANDSHAKE_TRAFFIC_SECRET"; + break; + case CLIENT_TRAFFIC_SECRET: + label = "CLIENT_TRAFFIC_SECRET_0"; + break; + case SERVER_TRAFFIC_SECRET: + label = "SERVER_TRAFFIC_SECRET_0"; + break; + case EARLY_EXPORTER_SECRET: + label = "EARLY_EXPORTER_SECRET"; + break; + case EXPORTER_SECRET: + label = "EXPORTER_SECRET"; + break; + default: + return 0; + } + + if(SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE) == 0) { + /* Should never happen as wolfSSL_KeepArrays() was called before. */ + return 0; + } + + Curl_tls_keylog_write(label, client_random, secret, secretSz); + return 0; +} +#endif /* defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) */ + +static void +wolfssl_log_tls12_secret(SSL *ssl) +{ + unsigned char *ms, *sr, *cr; + unsigned int msLen, srLen, crLen, i, x = 0; + +#if LIBWOLFSSL_VERSION_HEX >= 0x0300d000 /* >= 3.13.0 */ + /* wolfSSL_GetVersion is available since 3.13, we use it instead of + * SSL_version since the latter relies on OPENSSL_ALL (--enable-opensslall or + * --enable-all). Failing to perform this check could result in an unusable + * key log line when TLS 1.3 is actually negotiated. */ + switch(wolfSSL_GetVersion(ssl)) { + case WOLFSSL_SSLV3: + case WOLFSSL_TLSV1: + case WOLFSSL_TLSV1_1: + case WOLFSSL_TLSV1_2: + break; + default: + /* TLS 1.3 does not use this mechanism, the "master secret" returned below + * is not directly usable. */ + return; + } +#endif + + if(SSL_get_keys(ssl, &ms, &msLen, &sr, &srLen, &cr, &crLen) != SSL_SUCCESS) { + return; + } + + /* Check for a missing master secret and skip logging. That can happen if + * curl rejects the server certificate and aborts the handshake. + */ + for(i = 0; i < msLen; i++) { + x |= ms[i]; + } + if(x == 0) { + return; + } + + Curl_tls_keylog_write("CLIENT_RANDOM", cr, ms, msLen); +} +#endif /* OPENSSL_EXTRA */ + static int do_file_type(const char *type) { if(!type || !type[0]) @@ -222,8 +222,8 @@ wolfssl_connect_step1(struct connectdata *conn, { char *ciphers; struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; SSL_METHOD* req_method = NULL; curl_socket_t sockfd = conn->sock[sockindex]; #ifdef HAVE_SNI @@ -303,11 +303,11 @@ wolfssl_connect_step1(struct connectdata *conn, 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; } @@ -322,11 +322,11 @@ wolfssl_connect_step1(struct connectdata *conn, * defaults to TLS 1.1) so we have this short circuit evaluation to find * the minimum supported TLS version. */ - if((wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1) != 1) && - (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_1) != 1) && - (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_2) != 1) + if((wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1) != 1) && + (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_1) != 1) && + (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_2) != 1) #ifdef WOLFSSL_TLS13 - && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_3) != 1) + && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_3) != 1) #endif ) { failf(data, "SSL: couldn't set the minimum protocol version"); @@ -338,7 +338,7 @@ wolfssl_connect_step1(struct connectdata *conn, ciphers = SSL_CONN_CONFIG(cipher_list); if(ciphers) { - 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; } @@ -348,13 +348,13 @@ wolfssl_connect_step1(struct connectdata *conn, #ifndef NO_FILESYSTEM /* load trusted cacert */ if(SSL_CONN_CONFIG(CAfile)) { - if(1 != SSL_CTX_load_verify_locations(backend->ctx, + if(1 != SSL_CTX_load_verify_locations(backend->ctx, SSL_CONN_CONFIG(CAfile), SSL_CONN_CONFIG(CApath))) { if(SSL_CONN_CONFIG(verifypeer)) { /* Fail if we insist on successfully verifying the server. */ - failf(data, "error setting certificate verify locations:" - " CAfile: %s CApath: %s", + failf(data, "error setting certificate verify locations:" + " CAfile: %s CApath: %s", SSL_CONN_CONFIG(CAfile)? SSL_CONN_CONFIG(CAfile): "none", SSL_CONN_CONFIG(CApath)? @@ -372,26 +372,26 @@ wolfssl_connect_step1(struct connectdata *conn, /* Everything is fine. */ infof(data, "successfully set certificate verify locations:\n"); } - infof(data, " CAfile: %s\n", - SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none"); - infof(data, " CApath: %s\n", - SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath) : "none"); + infof(data, " CAfile: %s\n", + SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none"); + infof(data, " CApath: %s\n", + SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath) : "none"); } /* Load the client certificate, and private key */ - if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) { + 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_file(backend->ctx, - SSL_SET_OPTION(primary.clientcert), - file_type) != 1) { + if(SSL_CTX_use_certificate_file(backend->ctx, + SSL_SET_OPTION(primary.clientcert), + file_type) != 1) { failf(data, "unable to use client certificate (no key or wrong pass" " phrase?)"); return CURLE_SSL_CONNECT_ERROR; } file_type = do_file_type(SSL_SET_OPTION(key_type)); - if(SSL_CTX_use_PrivateKey_file(backend->ctx, SSL_SET_OPTION(key), + if(SSL_CTX_use_PrivateKey_file(backend->ctx, SSL_SET_OPTION(key), file_type) != 1) { failf(data, "unable to set private key"); return CURLE_SSL_CONNECT_ERROR; @@ -403,7 +403,7 @@ wolfssl_connect_step1(struct connectdata *conn, * fail to connect if the verification fails, or if it should continue * anyway. In the latter case the result of the verification is checked with * SSL_get_verify_result() below. */ - SSL_CTX_set_verify(backend->ctx, + SSL_CTX_set_verify(backend->ctx, SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER: SSL_VERIFY_NONE, NULL); @@ -414,19 +414,19 @@ wolfssl_connect_step1(struct connectdata *conn, #ifdef ENABLE_IPV6 struct in6_addr addr6; #endif -#ifndef CURL_DISABLE_PROXY +#ifndef CURL_DISABLE_PROXY const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; -#else - const char * const hostname = conn->host.name; -#endif +#else + const char * const hostname = conn->host.name; +#endif size_t hostname_len = strlen(hostname); if((hostname_len < USHRT_MAX) && (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) && #ifdef ENABLE_IPV6 (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) && #endif - (wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, hostname, + (wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, hostname, (unsigned short)hostname_len) != 1)) { infof(data, "WARNING: failed to configure server name indication (SNI) " "TLS extension\n"); @@ -436,7 +436,7 @@ wolfssl_connect_step1(struct connectdata *conn, /* give application a chance to interfere with SSL set up. */ if(data->set.ssl.fsslctx) { - CURLcode result = (*data->set.ssl.fsslctx)(data, backend->ctx, + CURLcode result = (*data->set.ssl.fsslctx)(data, backend->ctx, data->set.ssl.fsslctxp); if(result) { failf(data, "error signaled by ssl ctx callback"); @@ -454,10 +454,10 @@ wolfssl_connect_step1(struct connectdata *conn, #endif /* Let's make an SSL structure */ - 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; } @@ -480,7 +480,7 @@ wolfssl_connect_step1(struct connectdata *conn, strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1); infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - if(wolfSSL_UseALPN(backend->handle, protocols, + if(wolfSSL_UseALPN(backend->handle, protocols, (unsigned)strlen(protocols), WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) { failf(data, "SSL: failed setting ALPN protocols"); @@ -489,17 +489,17 @@ wolfssl_connect_step1(struct connectdata *conn, } #endif /* HAVE_ALPN */ -#ifdef OPENSSL_EXTRA - if(Curl_tls_keylog_enabled()) { - /* Ensure the Client Random is preserved. */ - wolfSSL_KeepArrays(backend->handle); -#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) - wolfSSL_set_tls13_secret_cb(backend->handle, - wolfssl_tls13_secret_callback, NULL); -#endif - } -#endif /* OPENSSL_EXTRA */ - +#ifdef OPENSSL_EXTRA + if(Curl_tls_keylog_enabled()) { + /* Ensure the Client Random is preserved. */ + wolfSSL_KeepArrays(backend->handle); +#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) + wolfSSL_set_tls13_secret_cb(backend->handle, + wolfssl_tls13_secret_callback, NULL); +#endif + } +#endif /* OPENSSL_EXTRA */ + /* Check if there's a cached ID we can/should use here! */ if(SSL_SET_OPTION(primary.sessionid)) { void *ssl_sessionid = NULL; @@ -507,11 +507,11 @@ wolfssl_connect_step1(struct connectdata *conn, Curl_ssl_sessionid_lock(conn); if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { /* we got a session id, use it! */ - if(!SSL_set_session(backend->handle, ssl_sessionid)) { + if(!SSL_set_session(backend->handle, ssl_sessionid)) { char error_buffer[WOLFSSL_MAX_ERROR_SZ]; Curl_ssl_sessionid_unlock(conn); failf(data, "SSL: SSL_set_session failed: %s", - ERR_error_string(SSL_get_error(backend->handle, 0), + ERR_error_string(SSL_get_error(backend->handle, 0), error_buffer)); return CURLE_SSL_CONNECT_ERROR; } @@ -522,7 +522,7 @@ wolfssl_connect_step1(struct connectdata *conn, } /* pass the raw socket into the SSL layer */ - if(!SSL_set_fd(backend->handle, (int)sockfd)) { + if(!SSL_set_fd(backend->handle, (int)sockfd)) { failf(data, "SSL: SSL_set_fd failed"); return CURLE_SSL_CONNECT_ERROR; } @@ -538,62 +538,62 @@ wolfssl_connect_step2(struct connectdata *conn, { int ret = -1; struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; -#ifndef CURL_DISABLE_PROXY + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; +#ifndef CURL_DISABLE_PROXY const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; const char * const dispname = SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname; const char * const pinnedpubkey = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; -#else - const char * const hostname = conn->host.name; - const char * const dispname = conn->host.dispname; - const char * const pinnedpubkey = - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; -#endif + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; +#else + const char * const hostname = conn->host.name; + const char * const dispname = conn->host.dispname; + const char * const pinnedpubkey = + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; +#endif conn->recv[sockindex] = wolfssl_recv; conn->send[sockindex] = wolfssl_send; /* Enable RFC2818 checks */ if(SSL_CONN_CONFIG(verifyhost)) { - ret = wolfSSL_check_domain_name(backend->handle, hostname); + ret = wolfSSL_check_domain_name(backend->handle, hostname); if(ret == SSL_FAILURE) return CURLE_OUT_OF_MEMORY; } - ret = SSL_connect(backend->handle); - -#ifdef OPENSSL_EXTRA - if(Curl_tls_keylog_enabled()) { - /* If key logging is enabled, wait for the handshake to complete and then - * proceed with logging secrets (for TLS 1.2 or older). - * - * During the handshake (ret==-1), wolfSSL_want_read() is true as it waits - * for the server response. At that point the master secret is not yet - * available, so we must not try to read it. - * To log the secret on completion with a handshake failure, detect - * completion via the observation that there is nothing to read or write. - * Note that OpenSSL SSL_want_read() is always true here. If wolfSSL ever - * changes, the worst case is that no key is logged on error. - */ - if(ret == SSL_SUCCESS || - (!wolfSSL_want_read(backend->handle) && - !wolfSSL_want_write(backend->handle))) { - wolfssl_log_tls12_secret(backend->handle); - /* Client Random and master secrets are no longer needed, erase these. - * Ignored while the handshake is still in progress. */ - wolfSSL_FreeArrays(backend->handle); - } - } -#endif /* OPENSSL_EXTRA */ - + ret = SSL_connect(backend->handle); + +#ifdef OPENSSL_EXTRA + if(Curl_tls_keylog_enabled()) { + /* If key logging is enabled, wait for the handshake to complete and then + * proceed with logging secrets (for TLS 1.2 or older). + * + * During the handshake (ret==-1), wolfSSL_want_read() is true as it waits + * for the server response. At that point the master secret is not yet + * available, so we must not try to read it. + * To log the secret on completion with a handshake failure, detect + * completion via the observation that there is nothing to read or write. + * Note that OpenSSL SSL_want_read() is always true here. If wolfSSL ever + * changes, the worst case is that no key is logged on error. + */ + if(ret == SSL_SUCCESS || + (!wolfSSL_want_read(backend->handle) && + !wolfSSL_want_write(backend->handle))) { + wolfssl_log_tls12_secret(backend->handle); + /* Client Random and master secrets are no longer needed, erase these. + * Ignored while the handshake is still in progress. */ + wolfSSL_FreeArrays(backend->handle); + } + } +#endif /* OPENSSL_EXTRA */ + if(ret != 1) { char error_buffer[WOLFSSL_MAX_ERROR_SZ]; - int detail = SSL_get_error(backend->handle, ret); + int detail = SSL_get_error(backend->handle, ret); if(SSL_ERROR_WANT_READ == detail) { connssl->connecting_state = ssl_connect_2_reading; @@ -658,11 +658,11 @@ wolfssl_connect_step2(struct connectdata *conn, X509 *x509; const char *x509_der; int x509_der_len; - struct Curl_X509certificate x509_parsed; - struct Curl_asn1Element *pubkey; + struct Curl_X509certificate x509_parsed; + struct Curl_asn1Element *pubkey; CURLcode result; - x509 = SSL_get_peer_certificate(backend->handle); + x509 = SSL_get_peer_certificate(backend->handle); if(!x509) { failf(data, "SSL: failed retrieving server certificate"); return CURLE_SSL_PINNEDPUBKEYNOTMATCH; @@ -704,7 +704,7 @@ wolfssl_connect_step2(struct connectdata *conn, char *protocol = NULL; unsigned short protocol_len = 0; - rc = wolfSSL_ALPN_GetProtocol(backend->handle, &protocol, &protocol_len); + rc = wolfSSL_ALPN_GetProtocol(backend->handle, &protocol, &protocol_len); if(rc == SSL_SUCCESS) { infof(data, "ALPN, server accepted to use %.*s\n", protocol_len, @@ -738,8 +738,8 @@ wolfssl_connect_step2(struct connectdata *conn, connssl->connecting_state = ssl_connect_3; #if (LIBWOLFSSL_VERSION_HEX >= 0x03009010) infof(data, "SSL connection using %s / %s\n", - wolfSSL_get_version(backend->handle), - wolfSSL_get_cipher_name(backend->handle)); + wolfSSL_get_version(backend->handle), + wolfSSL_get_cipher_name(backend->handle)); #else infof(data, "SSL connected\n"); #endif @@ -755,7 +755,7 @@ wolfssl_connect_step3(struct connectdata *conn, CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); @@ -764,7 +764,7 @@ wolfssl_connect_step3(struct connectdata *conn, SSL_SESSION *our_ssl_sessionid; void *old_ssl_sessionid = NULL; - our_ssl_sessionid = SSL_get_session(backend->handle); + our_ssl_sessionid = SSL_get_session(backend->handle); Curl_ssl_sessionid_lock(conn); incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, @@ -802,13 +802,13 @@ static ssize_t wolfssl_send(struct connectdata *conn, CURLcode *curlcode) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; char error_buffer[WOLFSSL_MAX_ERROR_SZ]; - int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; - int rc = SSL_write(backend->handle, mem, memlen); + int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; + 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: @@ -830,33 +830,33 @@ static ssize_t wolfssl_send(struct connectdata *conn, static void Curl_wolfssl_close(struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; - 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; } } static ssize_t wolfssl_recv(struct connectdata *conn, - int num, - char *buf, - size_t buffersize, - CURLcode *curlcode) + int num, + char *buf, + size_t buffersize, + CURLcode *curlcode) { struct ssl_connect_data *connssl = &conn->ssl[num]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; char error_buffer[WOLFSSL_MAX_ERROR_SZ]; - int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; - int nread = SSL_read(backend->handle, buf, buffsize); + int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; + 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 */ @@ -897,9 +897,9 @@ static size_t Curl_wolfssl_version(char *buffer, size_t size) static int Curl_wolfssl_init(void) { -#ifdef OPENSSL_EXTRA - Curl_tls_keylog_open(); -#endif +#ifdef OPENSSL_EXTRA + Curl_tls_keylog_open(); +#endif return (wolfSSL_Init() == SSL_SUCCESS); } @@ -907,19 +907,19 @@ static int Curl_wolfssl_init(void) static void Curl_wolfssl_cleanup(void) { wolfSSL_Cleanup(); -#ifdef OPENSSL_EXTRA - Curl_tls_keylog_close(); -#endif +#ifdef OPENSSL_EXTRA + Curl_tls_keylog_close(); +#endif } -static bool Curl_wolfssl_data_pending(const struct connectdata *conn, - int connindex) +static bool Curl_wolfssl_data_pending(const struct connectdata *conn, + int connindex) { const struct ssl_connect_data *connssl = &conn->ssl[connindex]; - struct ssl_backend_data *backend = connssl->backend; - if(backend->handle) /* SSL is in use */ - return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE; + struct ssl_backend_data *backend = connssl->backend; + if(backend->handle) /* SSL is in use */ + return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE; else return FALSE; } @@ -933,11 +933,11 @@ static int Curl_wolfssl_shutdown(struct connectdata *conn, int sockindex) { int retval = 0; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; - if(backend->handle) { - SSL_free(backend->handle); - backend->handle = NULL; + if(backend->handle) { + SSL_free(backend->handle); + backend->handle = NULL; } return retval; } @@ -963,7 +963,7 @@ wolfssl_connect_common(struct connectdata *conn, if(ssl_connect_1 == connssl->connecting_state) { /* Find out how much more time we're allowed */ - const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); if(timeout_ms < 0) { /* no need to continue if time already is up */ @@ -981,7 +981,7 @@ wolfssl_connect_common(struct connectdata *conn, ssl_connect_2_writing == connssl->connecting_state) { /* check allowed time left */ - const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); if(timeout_ms < 0) { /* no need to continue if time already is up */ @@ -1080,7 +1080,7 @@ static CURLcode Curl_wolfssl_connect(struct connectdata *conn, int sockindex) static CURLcode Curl_wolfssl_random(struct Curl_easy *data, unsigned char *entropy, size_t length) { - WC_RNG rng; + WC_RNG rng; (void)data; if(wc_InitRng(&rng)) return CURLE_FAILED_INIT; @@ -1094,11 +1094,11 @@ static CURLcode Curl_wolfssl_random(struct Curl_easy *data, } static CURLcode Curl_wolfssl_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum /* output */, - size_t unused) + size_t tmplen, + unsigned char *sha256sum /* output */, + size_t unused) { - wc_Sha256 SHA256pw; + wc_Sha256 SHA256pw; (void)unused; wc_InitSha256(&SHA256pw); wc_Sha256Update(&SHA256pw, tmp, (word32)tmplen); @@ -1107,11 +1107,11 @@ static CURLcode Curl_wolfssl_sha256sum(const unsigned char *tmp, /* input */ } static void *Curl_wolfssl_get_internals(struct ssl_connect_data *connssl, - CURLINFO info UNUSED_PARAM) + CURLINFO info UNUSED_PARAM) { - struct ssl_backend_data *backend = connssl->backend; + struct ssl_backend_data *backend = connssl->backend; (void)info; - return backend->handle; + return backend->handle; } const struct Curl_ssl Curl_ssl_wolfssl = { diff --git a/contrib/libs/curl/lib/vtls/wolfssl.h b/contrib/libs/curl/lib/vtls/wolfssl.h index d411e6913e..7c8b9e07dd 100644 --- a/contrib/libs/curl/lib/vtls/wolfssl.h +++ b/contrib/libs/curl/lib/vtls/wolfssl.h @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 - * are also available at https://curl.se/docs/copyright.html. + * are also available at https://curl.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is |