summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/vtls
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2018-12-14 03:33:12 +0300
committerdartraiden <wowemuh@gmail.com>2018-12-14 03:33:29 +0300
commitfff280ec7c91e7bbba1f8dd389468717f08e9106 (patch)
treeae20777655e2814dd5ab9be0e456a472065e62ce /libs/libcurl/src/vtls
parent887544273011d56a796e9507199ea8d6484d31c6 (diff)
libcurl: update to 7.63
Diffstat (limited to 'libs/libcurl/src/vtls')
-rw-r--r--libs/libcurl/src/vtls/axtls.c741
-rw-r--r--libs/libcurl/src/vtls/axtls.h33
-rw-r--r--libs/libcurl/src/vtls/cyassl.c8
-rw-r--r--libs/libcurl/src/vtls/darwinssl.c26
-rw-r--r--libs/libcurl/src/vtls/gskit.c2
-rw-r--r--libs/libcurl/src/vtls/gtls.c26
-rw-r--r--libs/libcurl/src/vtls/mbedtls.c6
-rw-r--r--libs/libcurl/src/vtls/mesalink.c6
-rw-r--r--libs/libcurl/src/vtls/nss.c72
-rw-r--r--libs/libcurl/src/vtls/openssl.c252
-rw-r--r--libs/libcurl/src/vtls/polarssl.c8
-rw-r--r--libs/libcurl/src/vtls/schannel.c83
-rw-r--r--libs/libcurl/src/vtls/schannel.h4
-rw-r--r--libs/libcurl/src/vtls/schannel_verify.c4
-rw-r--r--libs/libcurl/src/vtls/vtls.c16
-rw-r--r--libs/libcurl/src/vtls/vtls.h1
16 files changed, 335 insertions, 953 deletions
diff --git a/libs/libcurl/src/vtls/axtls.c b/libs/libcurl/src/vtls/axtls.c
deleted file mode 100644
index b262392a00..0000000000
--- a/libs/libcurl/src/vtls/axtls.c
+++ /dev/null
@@ -1,741 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>.
- * Copyright (C) 2010 - 2018, 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.haxx.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.
- *
- ***************************************************************************/
-
-/*
- * Source file for all axTLS-specific code for the TLS/SSL layer. No code
- * but vtls.c should ever call or use these functions.
- */
-
-#include "curl_setup.h"
-
-#ifdef USE_AXTLS
-
-#error axTLS support has been disabled in curl due to doubts about quality,
-#error user dedication and a lack of use/testing. We urge users to consider
-#error using a more established TLS backend instead.
-
-#include <axTLS/config.h>
-#include <axTLS/ssl.h>
-#include "axtls.h"
-
-#include "sendf.h"
-#include "inet_pton.h"
-#include "vtls.h"
-#include "parsedate.h"
-#include "connect.h" /* for the connect timeout */
-#include "select.h"
-#include "curl_printf.h"
-#include "hostcheck.h"
-#include <unistd.h>
-
-/* The last #include files should be: */
-#include "curl_memory.h"
-#include "memdebug.h"
-
-struct ssl_backend_data {
- SSL_CTX* ssl_ctx;
- SSL* ssl;
-};
-
-#define BACKEND connssl->backend
-
-static CURLcode map_error_to_curl(int axtls_err)
-{
- switch(axtls_err) {
- case SSL_ERROR_NOT_SUPPORTED:
- case SSL_ERROR_INVALID_VERSION:
- case -70: /* protocol version alert from server */
- return CURLE_UNSUPPORTED_PROTOCOL;
- break;
- case SSL_ERROR_NO_CIPHER:
- return CURLE_SSL_CIPHER;
- break;
- case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
- case SSL_ERROR_NO_CERT_DEFINED:
- case -42: /* bad certificate alert from server */
- case -43: /* unsupported cert alert from server */
- case -44: /* cert revoked alert from server */
- case -45: /* cert expired alert from server */
- case -46: /* cert unknown alert from server */
- return CURLE_SSL_CERTPROBLEM;
- break;
- case SSL_X509_ERROR(X509_NOT_OK):
- case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
- case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
- case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
- case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
- case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
- case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
- case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
- case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
- return CURLE_PEER_FAILED_VERIFICATION;
- break;
- case -48: /* unknown ca alert from server */
- return CURLE_SSL_CACERT;
- break;
- case -49: /* access denied alert from server */
- return CURLE_REMOTE_ACCESS_DENIED;
- break;
- case SSL_ERROR_CONN_LOST:
- case SSL_ERROR_SOCK_SETUP_FAILURE:
- case SSL_ERROR_INVALID_HANDSHAKE:
- case SSL_ERROR_INVALID_PROT_MSG:
- case SSL_ERROR_INVALID_HMAC:
- case SSL_ERROR_INVALID_SESSION:
- case SSL_ERROR_INVALID_KEY: /* it's too bad this doesn't map better */
- case SSL_ERROR_FINISHED_INVALID:
- case SSL_ERROR_NO_CLIENT_RENOG:
- default:
- return CURLE_SSL_CONNECT_ERROR;
- break;
- }
-}
-
-static Curl_recv axtls_recv;
-static Curl_send axtls_send;
-
-static void free_ssl_structs(struct ssl_connect_data *connssl)
-{
- if(BACKEND->ssl) {
- ssl_free(BACKEND->ssl);
- BACKEND->ssl = NULL;
- }
- if(BACKEND->ssl_ctx) {
- ssl_ctx_free(BACKEND->ssl_ctx);
- BACKEND->ssl_ctx = NULL;
- }
-}
-
-/*
- * For both blocking and non-blocking connects, this function sets up the
- * ssl context and state. This function is called after the TCP connect
- * has completed.
- */
-static CURLcode connect_prep(struct connectdata *conn, int sockindex)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct Curl_easy *data = conn->data;
- SSL_CTX *ssl_ctx;
- SSL *ssl = NULL;
- int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
- int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
- int i, ssl_fcn_return;
-
- /* Assuming users will not compile in custom key/cert to axTLS.
- * Also, even for blocking connects, use axTLS non-blocking feature.
- */
- uint32_t client_option = SSL_NO_DEFAULT_KEY |
- SSL_SERVER_VERIFY_LATER |
- SSL_CONNECT_IN_PARTS;
-
- if(connssl->state == ssl_connection_complete)
- /* to make us tolerant against being called more than once for the
- same connection */
- return CURLE_OK;
-
- if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
- failf(data, "axtls does not support CURL_SSLVERSION_MAX");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
-
- /* axTLS only supports TLSv1 */
- /* check to see if we've been told to use an explicit SSL/TLS version */
- switch(SSL_CONN_CONFIG(version)) {
- case CURL_SSLVERSION_DEFAULT:
- case CURL_SSLVERSION_TLSv1:
- break;
- default:
- failf(data, "axTLS only supports TLS 1.0 and 1.1, "
- "and it cannot be specified which one to use");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
-#ifdef AXTLSDEBUG
- client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
-#endif /* AXTLSDEBUG */
-
- /* Allocate an SSL_CTX struct */
- ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
- if(ssl_ctx == NULL) {
- failf(data, "unable to create client SSL context");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- BACKEND->ssl_ctx = ssl_ctx;
- BACKEND->ssl = NULL;
-
- /* Load the trusted CA cert bundle file */
- if(SSL_CONN_CONFIG(CAfile)) {
- if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT,
- SSL_CONN_CONFIG(CAfile), NULL) != SSL_OK) {
- infof(data, "error reading ca cert file %s \n",
- SSL_CONN_CONFIG(CAfile));
- if(SSL_CONN_CONFIG(verifypeer)) {
- return CURLE_SSL_CACERT_BADFILE;
- }
- }
- else
- infof(data, "found certificates in %s\n", SSL_CONN_CONFIG(CAfile));
- }
-
- /* gtls.c tasks we're skipping for now:
- * 1) certificate revocation list checking
- * 2) dns name assignment to host
- * 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore
- * 4) set certificate priority. axTLS ignores type and sends certs in
- * order added. can probably ignore this.
- */
-
- /* Load client certificate */
- if(SSL_SET_OPTION(cert)) {
- i = 0;
- /* Instead of trying to analyze cert type here, let axTLS try them all. */
- while(cert_types[i] != 0) {
- ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
- SSL_SET_OPTION(cert), NULL);
- if(ssl_fcn_return == SSL_OK) {
- infof(data, "successfully read cert file %s \n",
- SSL_SET_OPTION(cert));
- break;
- }
- i++;
- }
- /* Tried all cert types, none worked. */
- if(cert_types[i] == 0) {
- failf(data, "%s is not x509 or pkcs12 format",
- SSL_SET_OPTION(cert));
- return CURLE_SSL_CERTPROBLEM;
- }
- }
-
- /* Load client key.
- If a pkcs12 file successfully loaded a cert, then there's nothing to do
- because the key has already been loaded. */
- if(SSL_SET_OPTION(key) && cert_types[i] != SSL_OBJ_PKCS12) {
- i = 0;
- /* Instead of trying to analyze key type here, let axTLS try them all. */
- while(key_types[i] != 0) {
- ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
- SSL_SET_OPTION(key), NULL);
- if(ssl_fcn_return == SSL_OK) {
- infof(data, "successfully read key file %s \n",
- SSL_SET_OPTION(key));
- break;
- }
- i++;
- }
- /* Tried all key types, none worked. */
- if(key_types[i] == 0) {
- failf(data, "Failure: %s is not a supported key file",
- SSL_SET_OPTION(key));
- return CURLE_SSL_CONNECT_ERROR;
- }
- }
-
- /* gtls.c does more here that is being left out for now
- * 1) set session credentials. can probably ignore since axtls puts this
- * info in the ssl_ctx struct
- * 2) setting up callbacks. these seem gnutls specific
- */
-
- if(SSL_SET_OPTION(primary.sessionid)) {
- const uint8_t *ssl_sessionid;
- size_t ssl_idsize;
-
- /* In axTLS, handshaking happens inside ssl_client_new. */
- Curl_ssl_sessionid_lock(conn);
- if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize,
- sockindex)) {
- /* we got a session id, use it! */
- infof(data, "SSL re-using session ID\n");
- ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
- ssl_sessionid, (uint8_t)ssl_idsize, NULL);
- }
- Curl_ssl_sessionid_unlock(conn);
- }
-
- if(!ssl)
- ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0, NULL);
-
- BACKEND->ssl = ssl;
- return CURLE_OK;
-}
-
-static void Curl_axtls_close(struct connectdata *conn, int sockindex)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-
- infof(conn->data, " Curl_axtls_close\n");
-
- /* line from openssl.c: (void)SSL_shutdown(BACKEND->ssl);
- axTLS compat layer does nothing for SSL_shutdown */
-
- /* The following line is from openssl.c. There seems to be no axTLS
- equivalent. ssl_free and ssl_ctx_free close things.
- SSL_set_connect_state(connssl->handle); */
-
- free_ssl_structs(connssl);
-}
-
-/*
- * For both blocking and non-blocking connects, this function finalizes the
- * SSL connection.
- */
-static CURLcode connect_finish(struct connectdata *conn, int sockindex)
-{
- struct Curl_easy *data = conn->data;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- SSL *ssl = BACKEND->ssl;
- const char *peer_CN;
- uint32_t dns_altname_index;
- const char *dns_altname;
- int8_t found_subject_alt_names = 0;
- int8_t found_subject_alt_name_matching_conn = 0;
- 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;
-
- /* Here, gtls.c gets the peer certificates and fails out depending on
- * settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
- */
-
- /* Verify server's certificate */
- if(SSL_CONN_CONFIG(verifypeer)) {
- if(ssl_verify_cert(ssl) != SSL_OK) {
- Curl_axtls_close(conn, sockindex);
- failf(data, "server cert verify failed");
- return CURLE_PEER_FAILED_VERIFICATION;
- }
- }
- else
- infof(data, "\t server certificate verification SKIPPED\n");
-
- /* Here, gtls.c does issuer verification. axTLS has no straightforward
- * equivalent, so omitting for now.*/
-
- /* Here, gtls.c does the following
- * 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
- * it seems useful. This is now implemented, by Oscar Koeroo
- * 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
- * 3) displays a bunch of cert information. axTLS doesn't support most of
- * this, but a couple fields are available.
- */
-
- /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
- risk of an inifite loop */
- for(dns_altname_index = 0; ; dns_altname_index++) {
- dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
- if(dns_altname == NULL) {
- break;
- }
- found_subject_alt_names = 1;
-
- infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
- dns_altname, hostname);
- if(Curl_cert_hostcheck(dns_altname, hostname)) {
- found_subject_alt_name_matching_conn = 1;
- break;
- }
- }
-
- /* RFC2818 checks */
- if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
- if(SSL_CONN_CONFIG(verifyhost)) {
- /* Break connection ! */
- Curl_axtls_close(conn, sockindex);
- failf(data, "\tsubjectAltName(s) do not match %s\n", dispname);
- return CURLE_PEER_FAILED_VERIFICATION;
- }
- else
- infof(data, "\tsubjectAltName(s) do not match %s\n", dispname);
- }
- else if(found_subject_alt_names == 0) {
- /* Per RFC2818, when no Subject Alt Names were available, examine the peer
- CN as a legacy fallback */
- peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
- if(peer_CN == NULL) {
- if(SSL_CONN_CONFIG(verifyhost)) {
- Curl_axtls_close(conn, sockindex);
- failf(data, "unable to obtain common name from peer certificate");
- return CURLE_PEER_FAILED_VERIFICATION;
- }
- else
- infof(data, "unable to obtain common name from peer certificate");
- }
- else {
- if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
- if(SSL_CONN_CONFIG(verifyhost)) {
- /* Break connection ! */
- Curl_axtls_close(conn, sockindex);
- failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
- peer_CN, dispname);
- return CURLE_PEER_FAILED_VERIFICATION;
- }
- else
- infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
- peer_CN, dispname);
- }
- }
- }
-
- /* General housekeeping */
- connssl->state = ssl_connection_complete;
- conn->recv[sockindex] = axtls_recv;
- conn->send[sockindex] = axtls_send;
-
- /* Put our freshly minted SSL session in cache */
- if(SSL_SET_OPTION(primary.sessionid)) {
- const uint8_t *ssl_sessionid = ssl_get_session_id(ssl);
- size_t ssl_idsize = ssl_get_session_id_size(ssl);
- Curl_ssl_sessionid_lock(conn);
- if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize,
- sockindex) != CURLE_OK)
- infof(data, "failed to add session to cache\n");
- Curl_ssl_sessionid_unlock(conn);
- }
-
- return CURLE_OK;
-}
-
-/*
- * Use axTLS's non-blocking connection feature to open an SSL connection.
- * This is called after a TCP connection is already established.
- */
-static CURLcode Curl_axtls_connect_nonblocking(struct connectdata *conn,
- int sockindex, bool *done)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- CURLcode conn_step;
- int ssl_fcn_return;
- int i;
-
- *done = FALSE;
- /* connectdata is calloc'd and connecting_state is only changed in this
- function, so this is safe, as the state is effectively initialized. */
- if(connssl->connecting_state == ssl_connect_1) {
- conn_step = connect_prep(conn, sockindex);
- if(conn_step != CURLE_OK) {
- Curl_axtls_close(conn, sockindex);
- return conn_step;
- }
- connssl->connecting_state = ssl_connect_2;
- }
-
- if(connssl->connecting_state == ssl_connect_2) {
- /* Check to make sure handshake was ok. */
- if(ssl_handshake_status(BACKEND->ssl) != SSL_OK) {
- /* Loop to perform more work in between sleeps. This is work around the
- fact that axtls does not expose any knowledge about when work needs
- to be performed. This can save ~25% of time on SSL handshakes. */
- for(i = 0; i<5; i++) {
- ssl_fcn_return = ssl_read(BACKEND->ssl, NULL);
- if(ssl_fcn_return < 0) {
- Curl_axtls_close(conn, sockindex);
- ssl_display_error(ssl_fcn_return); /* goes to stdout. */
- return map_error_to_curl(ssl_fcn_return);
- }
- return CURLE_OK;
- }
- }
- infof(conn->data, "handshake completed successfully\n");
- connssl->connecting_state = ssl_connect_3;
- }
-
- if(connssl->connecting_state == ssl_connect_3) {
- conn_step = connect_finish(conn, sockindex);
- if(conn_step != CURLE_OK) {
- Curl_axtls_close(conn, sockindex);
- return conn_step;
- }
-
- /* Reset connect state */
- connssl->connecting_state = ssl_connect_1;
-
- *done = TRUE;
- return CURLE_OK;
- }
-
- /* Unrecognized state. Things are very bad. */
- connssl->state = ssl_connection_none;
- connssl->connecting_state = ssl_connect_1;
- /* Return value perhaps not strictly correct, but distinguishes the issue.*/
- return CURLE_BAD_FUNCTION_ARGUMENT;
-}
-
-
-/*
- * This function is called after the TCP connect has completed. Setup the TLS
- * layer and do all necessary magic for a blocking connect.
- */
-static CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex)
-{
- struct Curl_easy *data = conn->data;
- CURLcode conn_step = connect_prep(conn, sockindex);
- int ssl_fcn_return;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- SSL *ssl = BACKEND->ssl;
- long timeout_ms;
-
- if(conn_step != CURLE_OK) {
- Curl_axtls_close(conn, sockindex);
- return conn_step;
- }
-
- /* Check to make sure handshake was ok. */
- while(ssl_handshake_status(ssl) != SSL_OK) {
- /* 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;
- }
-
- ssl_fcn_return = ssl_read(ssl, NULL);
- if(ssl_fcn_return < 0) {
- Curl_axtls_close(conn, sockindex);
- ssl_display_error(ssl_fcn_return); /* goes to stdout. */
- return map_error_to_curl(ssl_fcn_return);
- }
- /* TODO: avoid polling */
- Curl_wait_ms(10);
- }
- infof(conn->data, "handshake completed successfully\n");
-
- conn_step = connect_finish(conn, sockindex);
- if(conn_step != CURLE_OK) {
- Curl_axtls_close(conn, sockindex);
- return conn_step;
- }
-
- return CURLE_OK;
-}
-
-/* return number of sent (non-SSL) bytes */
-static ssize_t axtls_send(struct connectdata *conn,
- int sockindex,
- const void *mem,
- size_t len,
- CURLcode *err)
-{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- /* ssl_write() returns 'int' while write() and send() returns 'size_t' */
- int rc = ssl_write(BACKEND->ssl, mem, (int)len);
-
- infof(conn->data, " axtls_send\n");
-
- if(rc < 0) {
- *err = map_error_to_curl(rc);
- rc = -1; /* generic error code for send failure */
- }
-
- *err = CURLE_OK;
- return rc;
-}
-
-/*
- * This function is called to shut down the SSL layer but keep the
- * socket open (CCC - Clear Command Channel)
- */
-static int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
-{
- /* Outline taken from openssl.c since functions are in axTLS compat layer.
- axTLS's error set is much smaller, so a lot of error-handling was removed.
- */
- int retval = 0;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct Curl_easy *data = conn->data;
- uint8_t *buf;
- ssize_t nread;
-
- infof(conn->data, " Curl_axtls_shutdown\n");
-
- /* This has only been tested on the proftpd server, and the mod_tls code
- sends a close notify alert without waiting for a close notify alert in
- response. Thus we wait for a close notify alert from the server, but
- we do not send one. Let's hope other servers do the same... */
-
- /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
- if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
- (void)SSL_shutdown(BACKEND->ssl);
- */
-
- if(BACKEND->ssl) {
- int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
- if(what > 0) {
- /* Something to read, let's do it and hope that it is the close
- notify alert from the server. buf is managed internally by
- axTLS and will be released upon calling ssl_free via
- free_ssl_structs. */
- nread = (ssize_t)ssl_read(BACKEND->ssl, &buf);
-
- if(nread < SSL_OK) {
- failf(data, "close notify alert not received during shutdown");
- retval = -1;
- }
- }
- else if(0 == what) {
- /* timeout */
- failf(data, "SSL shutdown timeout");
- }
- else {
- /* anything that gets here is fatally bad */
- failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
- retval = -1;
- }
-
- free_ssl_structs(connssl);
- }
- return retval;
-}
-
-static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
- int num, /* socketindex */
- char *buf, /* store read data here */
- size_t buffersize, /* max amount to read */
- CURLcode *err)
-{
- struct ssl_connect_data *connssl = &conn->ssl[num];
- ssize_t ret = 0;
- uint8_t *read_buf;
-
- infof(conn->data, " axtls_recv\n");
-
- *err = CURLE_OK;
- if(connssl) {
- ret = ssl_read(BACKEND->ssl, &read_buf);
- if(ret > SSL_OK) {
- /* ssl_read returns SSL_OK if there is more data to read, so if it is
- larger, then all data has been read already. */
- memcpy(buf, read_buf,
- (size_t)ret > buffersize ? buffersize : (size_t)ret);
- }
- else if(ret == SSL_OK) {
- /* more data to be read, signal caller to call again */
- *err = CURLE_AGAIN;
- ret = -1;
- }
- else if(ret == -3) {
- /* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
- team approves proposed fix. */
- Curl_axtls_close(conn, num);
- }
- else {
- failf(conn->data, "axTLS recv error (%d)", ret);
- *err = map_error_to_curl((int) ret);
- ret = -1;
- }
- }
-
- return ret;
-}
-
-/*
- * Return codes:
- * 1 means the connection is still in place
- * 0 means the connection has been closed
- * -1 means the connection status is unknown
- */
-static int Curl_axtls_check_cxn(struct connectdata *conn)
-{
- /* openssl.c line:
- rc = SSL_peek(conn->ssl[FIRSTSOCKET].backend->ssl, (void*)&buf, 1);
- axTLS compat layer always returns the last argument, so connection is
- always alive? */
-
- infof(conn->data, " Curl_axtls_check_cxn\n");
- return 1; /* connection still in place */
-}
-
-static void Curl_axtls_session_free(void *ptr)
-{
- (void)ptr;
- /* free the ID */
- /* both openssl.c and gtls.c do something here, but axTLS's OpenSSL
- compatibility layer does nothing, so we do nothing too. */
-}
-
-static size_t Curl_axtls_version(char *buffer, size_t size)
-{
- return snprintf(buffer, size, "axTLS/%s", ssl_version());
-}
-
-static CURLcode Curl_axtls_random(struct Curl_easy *data,
- unsigned char *entropy, size_t length)
-{
- static bool ssl_seeded = FALSE;
- (void)data;
- if(!ssl_seeded) {
- ssl_seeded = TRUE;
- /* Initialize the seed if not already done. This call is not exactly thread
- * safe (and neither is the ssl_seeded check), but the worst effect of a
- * race condition is that some global resources will leak. */
- RNG_initialize();
- }
- get_random((int)length, entropy);
- return CURLE_OK;
-}
-
-static void *Curl_axtls_get_internals(struct ssl_connect_data *connssl,
- CURLINFO info UNUSED_PARAM)
-{
- (void)info;
- return BACKEND->ssl;
-}
-
-const struct Curl_ssl Curl_ssl_axtls = {
- { CURLSSLBACKEND_AXTLS, "axtls" }, /* info */
- 0, /* no fancy stuff */
- sizeof(struct ssl_backend_data),
-
- /*
- * axTLS has no global init. Everything is done through SSL and SSL_CTX
- * structs stored in connectdata structure.
- */
- Curl_none_init, /* init */
- /* axTLS has no global cleanup. */
- Curl_none_cleanup, /* cleanup */
- Curl_axtls_version, /* version */
- Curl_axtls_check_cxn, /* check_cxn */
- Curl_axtls_shutdown, /* shutdown */
- Curl_none_data_pending, /* data_pending */
- Curl_axtls_random, /* random */
- Curl_none_cert_status_request, /* cert_status_request */
- Curl_axtls_connect, /* connect */
- Curl_axtls_connect_nonblocking, /* connect_nonblocking */
- Curl_axtls_get_internals, /* get_internals */
- Curl_axtls_close, /* close_one */
- Curl_none_close_all, /* close_all */
- Curl_axtls_session_free, /* session_free */
- Curl_none_set_engine, /* set_engine */
- Curl_none_set_engine_default, /* set_engine_default */
- Curl_none_engines_list, /* engines_list */
- Curl_none_false_start, /* false_start */
- Curl_none_md5sum, /* md5sum */
- NULL /* sha256sum */
-};
-
-#endif /* USE_AXTLS */
diff --git a/libs/libcurl/src/vtls/axtls.h b/libs/libcurl/src/vtls/axtls.h
deleted file mode 100644
index cb8187272d..0000000000
--- a/libs/libcurl/src/vtls/axtls.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef HEADER_CURL_AXTLS_H
-#define HEADER_CURL_AXTLS_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu@directv.com>
- * Copyright (C) 2010 - 2017, 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.haxx.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.
- *
- ***************************************************************************/
-
-#ifdef USE_AXTLS
-#include "curl/curl.h"
-#include "urldata.h"
-
-extern const struct Curl_ssl Curl_ssl_axtls;
-
-#endif /* USE_AXTLS */
-#endif /* HEADER_CURL_AXTLS_H */
diff --git a/libs/libcurl/src/vtls/cyassl.c b/libs/libcurl/src/vtls/cyassl.c
index e10398ac3f..0d45afbf0c 100644
--- a/libs/libcurl/src/vtls/cyassl.c
+++ b/libs/libcurl/src/vtls/cyassl.c
@@ -777,13 +777,13 @@ static void Curl_cyassl_session_free(void *ptr)
static size_t Curl_cyassl_version(char *buffer, size_t size)
{
#if LIBCYASSL_VERSION_HEX >= 0x03006000
- return snprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
+ return msnprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
#elif defined(WOLFSSL_VERSION)
- return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
+ return msnprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
#elif defined(CYASSL_VERSION)
- return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
+ return msnprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
#else
- return snprintf(buffer, size, "CyaSSL/%s", "<1.8.8");
+ return msnprintf(buffer, size, "CyaSSL/%s", "<1.8.8");
#endif
}
diff --git a/libs/libcurl/src/vtls/darwinssl.c b/libs/libcurl/src/vtls/darwinssl.c
index e8116b8a11..25b101282c 100644
--- a/libs/libcurl/src/vtls/darwinssl.c
+++ b/libs/libcurl/src/vtls/darwinssl.c
@@ -950,7 +950,7 @@ static CURLcode CopyCertSubject(struct Curl_easy *data,
if(!c) {
failf(data, "SSL: invalid CA certificate subject");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
}
/* If the subject is already available as UTF-8 encoded (ie 'direct') then
@@ -970,7 +970,7 @@ static CURLcode CopyCertSubject(struct Curl_easy *data,
if(!CFStringGetCString(c, cbuf, cbuf_size,
kCFStringEncodingUTF8)) {
failf(data, "SSL: invalid CA certificate subject");
- result = CURLE_SSL_CACERT;
+ result = CURLE_PEER_FAILED_VERIFICATION;
}
else
/* pass back the buffer */
@@ -1649,7 +1649,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
CFRelease(cert);
- if(result == CURLE_SSL_CACERT)
+ if(result == CURLE_PEER_FAILED_VERIFICATION)
return CURLE_SSL_CERTPROBLEM;
if(result)
return result;
@@ -2429,37 +2429,37 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
/* These are all certificate problems with the server: */
case errSSLXCertChainInvalid:
failf(data, "SSL certificate problem: Invalid certificate chain");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLUnknownRootCert:
failf(data, "SSL certificate problem: Untrusted root certificate");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLNoRootCert:
failf(data, "SSL certificate problem: No root certificate");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLCertNotYetValid:
failf(data, "SSL certificate problem: The certificate chain had a "
"certificate that is not yet valid");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLCertExpired:
case errSSLPeerCertExpired:
failf(data, "SSL certificate problem: Certificate chain had an "
"expired certificate");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLBadCert:
case errSSLPeerBadCert:
failf(data, "SSL certificate problem: Couldn't understand the server "
"certificate format");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLPeerUnsupportedCert:
failf(data, "SSL certificate problem: An unsupported certificate "
"format was encountered");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLPeerCertRevoked:
failf(data, "SSL certificate problem: The certificate was revoked");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
case errSSLPeerCertUnknown:
failf(data, "SSL certificate problem: The certificate is unknown");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
/* These are all certificate problems with the client: */
case errSecAuthFailed:
@@ -3015,7 +3015,7 @@ static void Curl_darwinssl_session_free(void *ptr)
static size_t Curl_darwinssl_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "SecureTransport");
+ return msnprintf(buffer, size, "SecureTransport");
}
/*
diff --git a/libs/libcurl/src/vtls/gskit.c b/libs/libcurl/src/vtls/gskit.c
index 8d1b3d6afc..c4afc89041 100644
--- a/libs/libcurl/src/vtls/gskit.c
+++ b/libs/libcurl/src/vtls/gskit.c
@@ -1314,7 +1314,7 @@ static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
static size_t Curl_gskit_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "GSKit");
+ return msnprintf(buffer, size, "GSKit");
}
diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c
index 37662a748f..9035ec483e 100644
--- a/libs/libcurl/src/vtls/gtls.c
+++ b/libs/libcurl/src/vtls/gtls.c
@@ -227,17 +227,17 @@ static void showtime(struct Curl_easy *data,
if(result)
return;
- snprintf(str,
- sizeof(str),
- "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
- text,
- Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
- tm->tm_mday,
- Curl_month[tm->tm_mon],
- tm->tm_year + 1900,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
+ msnprintf(str,
+ sizeof(str),
+ "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
+ text,
+ Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+ tm->tm_mday,
+ Curl_month[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
infof(data, "%s\n", str);
}
#endif
@@ -1110,7 +1110,7 @@ gtls_connect_step3(struct connectdata *conn,
"CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
"none",
SSL_SET_OPTION(CRLfile)?SSL_SET_OPTION(CRLfile):"none");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "\t server certificate verification FAILED\n");
@@ -1748,7 +1748,7 @@ static void Curl_gtls_session_free(void *ptr)
static size_t Curl_gtls_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
+ return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
}
#ifndef USE_GNUTLS_NETTLE
diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c
index c5ed8872ef..6a20e276e3 100644
--- a/libs/libcurl/src/vtls/mbedtls.c
+++ b/libs/libcurl/src/vtls/mbedtls.c
@@ -580,7 +580,7 @@ mbed_connect_step2(struct connectdata *conn,
if(ret & MBEDTLS_X509_BADCERT_REVOKED) {
failf(data, "Cert verify failed: BADCERT_REVOKED");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
}
if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH)
@@ -812,8 +812,8 @@ static void Curl_mbedtls_session_free(void *ptr)
static size_t Curl_mbedtls_version(char *buffer, size_t size)
{
unsigned int version = mbedtls_version_get_number();
- return snprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24,
- (version>>16)&0xff, (version>>8)&0xff);
+ return msnprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24,
+ (version>>16)&0xff, (version>>8)&0xff);
}
static CURLcode Curl_mbedtls_random(struct Curl_easy *data,
diff --git a/libs/libcurl/src/vtls/mesalink.c b/libs/libcurl/src/vtls/mesalink.c
index 6a2b67e633..db14115593 100644
--- a/libs/libcurl/src/vtls/mesalink.c
+++ b/libs/libcurl/src/vtls/mesalink.c
@@ -5,8 +5,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2017-2018, Yiming Jing, <jingyiming@baidu.com>
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com>
+ * Copyright (C) 1998 - 2018, 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
@@ -424,7 +424,7 @@ mesalink_recv(struct connectdata *conn, int num, char *buf, size_t buffersize,
static size_t
Curl_mesalink_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "MesaLink/%s", MESALINK_VERSION_STRING);
+ return msnprintf(buffer, size, "MesaLink/%s", MESALINK_VERSION_STRING);
}
static int
diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c
index a3d3e58bbe..08ee1aaaf2 100644
--- a/libs/libcurl/src/vtls/nss.c
+++ b/libs/libcurl/src/vtls/nss.c
@@ -246,6 +246,32 @@ static void nss_print_error_message(struct Curl_easy *data, PRUint32 err)
failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
}
+static char *nss_sslver_to_name(PRUint16 nssver)
+{
+ switch(nssver) {
+ case SSL_LIBRARY_VERSION_2:
+ return strdup("SSLv2");
+ case SSL_LIBRARY_VERSION_3_0:
+ return strdup("SSLv3");
+ case SSL_LIBRARY_VERSION_TLS_1_0:
+ return strdup("TLSv1.0");
+#ifdef SSL_LIBRARY_VERSION_TLS_1_1
+ case SSL_LIBRARY_VERSION_TLS_1_1:
+ return strdup("TLSv1.1");
+#endif
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+ case SSL_LIBRARY_VERSION_TLS_1_2:
+ return strdup("TLSv1.2");
+#endif
+#ifdef SSL_LIBRARY_VERSION_TLS_1_3
+ case SSL_LIBRARY_VERSION_TLS_1_3:
+ return strdup("TLSv1.3");
+#endif
+ default:
+ return curl_maprintf("0x%04x", nssver);
+ }
+}
+
static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
char *cipher_list)
{
@@ -1638,17 +1664,6 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version)
{
switch(version) {
- case CURL_SSLVERSION_TLSv1:
- /* TODO: set sslver->max to SSL_LIBRARY_VERSION_TLS_1_3 once stable */
-#ifdef SSL_LIBRARY_VERSION_TLS_1_2
- *nssver = SSL_LIBRARY_VERSION_TLS_1_2;
-#elif defined SSL_LIBRARY_VERSION_TLS_1_1
- *nssver = SSL_LIBRARY_VERSION_TLS_1_1;
-#else
- *nssver = SSL_LIBRARY_VERSION_TLS_1_0;
-#endif
- return CURLE_OK;
-
case CURL_SSLVERSION_SSLv2:
*nssver = SSL_LIBRARY_VERSION_2;
return CURLE_OK;
@@ -1709,10 +1724,8 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
}
switch(min) {
- case CURL_SSLVERSION_DEFAULT:
- break;
case CURL_SSLVERSION_TLSv1:
- sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+ case CURL_SSLVERSION_DEFAULT:
break;
default:
result = nss_sslver_from_curl(&sslver->min, min);
@@ -1789,10 +1802,19 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode result;
bool second_layer = FALSE;
+ SSLVersionRange sslver_supported;
SSLVersionRange sslver = {
SSL_LIBRARY_VERSION_TLS_1_0, /* min */
- SSL_LIBRARY_VERSION_TLS_1_0 /* max */
+#ifdef SSL_LIBRARY_VERSION_TLS_1_3
+ SSL_LIBRARY_VERSION_TLS_1_3 /* max */
+#elif defined SSL_LIBRARY_VERSION_TLS_1_2
+ SSL_LIBRARY_VERSION_TLS_1_2
+#elif defined SSL_LIBRARY_VERSION_TLS_1_1
+ SSL_LIBRARY_VERSION_TLS_1_1
+#else
+ SSL_LIBRARY_VERSION_TLS_1_0
+#endif
};
BACKEND->data = data;
@@ -1841,6 +1863,20 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
/* enable/disable the requested SSL version(s) */
if(nss_init_sslver(&sslver, data, conn) != CURLE_OK)
goto error;
+ if(SSL_VersionRangeGetSupported(ssl_variant_stream,
+ &sslver_supported) != SECSuccess)
+ goto error;
+ if(sslver_supported.max < sslver.max && sslver_supported.max >= sslver.min) {
+ char *sslver_req_str, *sslver_supp_str;
+ sslver_req_str = nss_sslver_to_name(sslver.max);
+ sslver_supp_str = nss_sslver_to_name(sslver_supported.max);
+ if(sslver_req_str && sslver_supp_str)
+ infof(data, "Falling back from %s to max supported SSL version (%s)\n",
+ sslver_req_str, sslver_supp_str);
+ free(sslver_req_str);
+ free(sslver_supp_str);
+ sslver.max = sslver_supported.max;
+ }
if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
goto error;
@@ -2090,7 +2126,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
result = CURLE_PEER_FAILED_VERIFICATION;
else if(*certverifyresult != 0)
- result = CURLE_SSL_CACERT;
+ result = CURLE_PEER_FAILED_VERIFICATION;
goto error;
}
@@ -2164,7 +2200,7 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
if(!blocking)
/* CURLE_AGAIN in non-blocking mode is not an error */
return CURLE_OK;
- /* fall through */
+ /* FALLTHROUGH */
default:
return result;
}
@@ -2279,7 +2315,7 @@ static ssize_t nss_recv(struct connectdata *conn, /* connection data */
static size_t Curl_nss_version(char *buffer, size_t size)
{
- return snprintf(buffer, size, "NSS/%s", NSS_VERSION);
+ return msnprintf(buffer, size, "NSS/%s", NSS_VERSION);
}
/* data might be NULL */
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index 4c5e8c19c0..8bddb9a8c6 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.c
@@ -69,7 +69,7 @@
#include <openssl/ocsp.h>
#endif
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && /* 0.9.8 or later */ \
+#if (OPENSSL_VERSION_NUMBER >= 0x0090700fL) && /* 0.9.7 or later */ \
!defined(OPENSSL_NO_ENGINE)
#define USE_OPENSSL_ENGINE
#include <openssl/engine.h>
@@ -82,6 +82,13 @@
#include "curl_memory.h"
#include "memdebug.h"
+/* Uncomment the ALLOW_RENEG line to a real #define if you want to allow TLS
+ renegotiations when built with BoringSSL. Renegotiating is non-compliant
+ with HTTP/2 and "an extremely dangerous protocol feature". Beware.
+
+#define ALLOW_RENEG 1
+ */
+
#ifndef OPENSSL_VERSION_NUMBER
#error "OPENSSL_VERSION_NUMBER not defined"
#endif
@@ -384,6 +391,31 @@ static char *ossl_strerror(unsigned long error, char *buf, size_t size)
return buf;
}
+/* Return an extra data index for the connection data.
+ * This index can be used with SSL_get_ex_data() and SSL_set_ex_data().
+ */
+static int ossl_get_ssl_conn_index(void)
+{
+ static int ssl_ex_data_conn_index = -1;
+ if(ssl_ex_data_conn_index < 0) {
+ ssl_ex_data_conn_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+ }
+ return ssl_ex_data_conn_index;
+}
+
+/* Return an extra data index for the sockindex.
+ * This index can be used with SSL_get_ex_data() and SSL_set_ex_data().
+ */
+static int ossl_get_ssl_sockindex_index(void)
+{
+ static int ssl_ex_data_sockindex_index = -1;
+ if(ssl_ex_data_sockindex_index < 0) {
+ ssl_ex_data_sockindex_index = SSL_get_ex_new_index(0, NULL, NULL, NULL,
+ NULL);
+ }
+ return ssl_ex_data_sockindex_index;
+}
+
static int passwd_callback(char *buf, int num, int encrypting,
void *global_passwd)
{
@@ -1035,6 +1067,10 @@ static int Curl_ossl_init(void)
}
#endif
+ /* Initialize the extra data indexes */
+ if(ossl_get_ssl_conn_index() < 0 || ossl_get_ssl_sockindex_index() < 0)
+ return 0;
+
return 1;
}
@@ -1049,7 +1085,7 @@ static void Curl_ossl_cleanup(void)
/* Free ciphers and digests lists */
EVP_cleanup();
-#ifdef HAVE_ENGINE_CLEANUP
+#ifdef USE_OPENSSL_ENGINE
/* Free engine list */
ENGINE_cleanup();
#endif
@@ -1867,15 +1903,8 @@ static const char *ssl_msg_type(int ssl_ver, int msg)
return "Unknown";
}
-static const char *tls_rt_type(int type, const void *buf, size_t buflen)
+static const char *tls_rt_type(int type)
{
- (void)buf;
- (void)buflen;
-#ifdef SSL3_RT_INNER_CONTENT_TYPE
- if(type == SSL3_RT_INNER_CONTENT_TYPE && buf && buflen >= 1)
- type = *(unsigned char *)buf;
-#endif
-
switch(type) {
#ifdef SSL3_RT_HEADER
case SSL3_RT_HEADER:
@@ -1945,12 +1974,20 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
case 0:
break;
default:
- snprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
+ msnprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
verstr = unknown;
break;
}
- if(ssl_ver) {
+ /* Log progress for interesting records only (like Handshake or Alert), skip
+ * all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0).
+ * For TLS 1.3, skip notification of the decrypted inner Content Type.
+ */
+ if(ssl_ver
+#ifdef SSL3_RT_INNER_CONTENT_TYPE
+ && content_type != SSL3_RT_INNER_CONTENT_TYPE
+#endif
+ ) {
const char *msg_name, *tls_rt_name;
char ssl_buf[1024];
int msg_type, txt_len;
@@ -1964,17 +2001,10 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
* is at 'buf[0]'.
*/
if(ssl_ver == SSL3_VERSION_MAJOR && content_type)
- tls_rt_name = tls_rt_type(content_type, buf, len);
+ tls_rt_name = tls_rt_type(content_type);
else
tls_rt_name = "";
-#ifdef SSL3_RT_INNER_CONTENT_TYPE
- if(content_type == SSL3_RT_INNER_CONTENT_TYPE) {
- msg_type = 0;
- msg_name = "[no content]";
- }
- else
-#endif
if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
msg_type = *(char *)buf;
msg_name = "Change cipher spec";
@@ -1988,9 +2018,9 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
msg_name = ssl_msg_type(ssl_ver, msg_type);
}
- txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
- verstr, direction?"OUT":"IN",
- tls_rt_name, msg_name, msg_type);
+ txt_len = msnprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
+ verstr, direction?"OUT":"IN",
+ tls_rt_name, msg_name, msg_type);
if(0 <= txt_len && (unsigned)txt_len < sizeof(ssl_buf)) {
Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len);
}
@@ -2137,6 +2167,7 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
}
#else
(void)sockindex;
+ (void)ctx_options;
failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
return CURLE_NOT_BUILT_IN;
#endif
@@ -2189,6 +2220,62 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
return CURLE_OK;
}
+/* The "new session" callback must return zero if the session can be removed
+ * or non-zero if the session has been put into the session cache.
+ */
+static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
+{
+ int res = 0;
+ struct connectdata *conn;
+ struct Curl_easy *data;
+ int sockindex;
+ curl_socket_t *sockindex_ptr;
+ int connectdata_idx = ossl_get_ssl_conn_index();
+ int sockindex_idx = ossl_get_ssl_sockindex_index();
+
+ if(connectdata_idx < 0 || sockindex_idx < 0)
+ return 0;
+
+ conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx);
+ if(!conn)
+ return 0;
+
+ data = conn->data;
+
+ /* The sockindex has been stored as a pointer to an array element */
+ sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx);
+ sockindex = (int)(sockindex_ptr - conn->sock);
+
+ if(SSL_SET_OPTION(primary.sessionid)) {
+ bool incache;
+ void *old_ssl_sessionid = NULL;
+
+ Curl_ssl_sessionid_lock(conn);
+ incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
+ sockindex));
+ if(incache) {
+ if(old_ssl_sessionid != ssl_sessionid) {
+ infof(data, "old SSL session ID is stale, removing\n");
+ Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+ incache = FALSE;
+ }
+ }
+
+ if(!incache) {
+ if(!Curl_ssl_addsessionid(conn, ssl_sessionid,
+ 0 /* unknown size */, sockindex)) {
+ /* the session has been put into the session cache */
+ res = 1;
+ }
+ else
+ failf(data, "failed to store ssl session");
+ }
+ Curl_ssl_sessionid_unlock(conn);
+ }
+
+ return res;
+}
+
static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
{
CURLcode result = CURLE_OK;
@@ -2585,6 +2672,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
}
#endif
+ /* Enable the session cache because it's a prerequisite for the "new session"
+ * callback. Use the "external storage" mode to avoid that OpenSSL creates
+ * an internal session cache.
+ */
+ 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);
+
/* give application a chance to interfere with SSL set up. */
if(data->set.ssl.fsslctx) {
result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
@@ -2610,6 +2705,10 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
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);
+#endif
+
SSL_set_connect_state(BACKEND->handle);
BACKEND->server_cert = 0x0;
@@ -2627,6 +2726,15 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
/* Check if there's a cached ID we can/should use here! */
if(SSL_SET_OPTION(primary.sessionid)) {
void *ssl_sessionid = NULL;
+ int connectdata_idx = ossl_get_ssl_conn_index();
+ int sockindex_idx = ossl_get_ssl_sockindex_index();
+
+ 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);
+ }
Curl_ssl_sessionid_lock(conn);
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
@@ -2721,14 +2829,14 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
if((lib == ERR_LIB_SSL) &&
(reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
- result = CURLE_SSL_CACERT;
+ result = CURLE_PEER_FAILED_VERIFICATION;
lerr = SSL_get_verify_result(BACKEND->handle);
if(lerr != X509_V_OK) {
*certverifyresult = lerr;
- snprintf(error_buffer, sizeof(error_buffer),
- "SSL certificate problem: %s",
- X509_verify_cert_error_string(lerr));
+ msnprintf(error_buffer, sizeof(error_buffer),
+ "SSL certificate problem: %s",
+ X509_verify_cert_error_string(lerr));
}
else
/* strcpy() is fine here as long as the string fits within
@@ -2839,7 +2947,7 @@ static void pubkey_show(struct Curl_easy *data,
char *ptr;
char namebuf[32];
- snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
+ msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
if(bn)
BN_print(mem, bn);
@@ -2900,8 +3008,8 @@ static int X509V3_ext(struct Curl_easy *data,
while((j<(size_t)biomem->length) && (biomem->data[j] == ' '))
j++;
if(j<(size_t)biomem->length)
- ptr += snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
- biomem->data[j]);
+ ptr += msnprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
+ biomem->data[j]);
}
Curl_ssl_push_certinfo(data, certnum, namebuf, buf);
@@ -3214,20 +3322,8 @@ static CURLcode servercert(struct connectdata *conn,
/* we've been asked to gather certificate info! */
(void)get_cert_chain(conn, connssl);
- 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)) );
- BIO_free(mem);
- return CURLE_OUT_OF_MEMORY;
- }
-
BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle);
if(!BACKEND->server_cert) {
- BIO_free(fp);
BIO_free(mem);
if(!strict)
return CURLE_OK;
@@ -3262,7 +3358,6 @@ static CURLcode servercert(struct connectdata *conn,
if(SSL_CONN_CONFIG(verifyhost)) {
result = verifyhost(conn, BACKEND->server_cert);
if(result) {
- BIO_free(fp);
X509_free(BACKEND->server_cert);
BACKEND->server_cert = NULL;
return result;
@@ -3284,6 +3379,18 @@ static CURLcode servercert(struct connectdata *conn,
/* e.g. match issuer name with provided issuer certificate */
if(SSL_SET_OPTION(issuercert)) {
+ 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)",
@@ -3319,6 +3426,7 @@ static CURLcode servercert(struct connectdata *conn,
infof(data, " SSL certificate issuer check ok (%s)\n",
SSL_SET_OPTION(issuercert));
+ BIO_free(fp);
X509_free(issuer);
}
@@ -3347,7 +3455,6 @@ static CURLcode servercert(struct connectdata *conn,
if(SSL_CONN_CONFIG(verifystatus)) {
result = verifystatus(conn, connssl);
if(result) {
- BIO_free(fp);
X509_free(BACKEND->server_cert);
BACKEND->server_cert = NULL;
return result;
@@ -3367,7 +3474,6 @@ static CURLcode servercert(struct connectdata *conn,
failf(data, "SSL: public key does not match pinned public key!");
}
- BIO_free(fp);
X509_free(BACKEND->server_cert);
BACKEND->server_cert = NULL;
connssl->connecting_state = ssl_connect_done;
@@ -3378,52 +3484,10 @@ static CURLcode servercert(struct connectdata *conn,
static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
{
CURLcode result = CURLE_OK;
- struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
- if(SSL_SET_OPTION(primary.sessionid)) {
- bool incache;
- SSL_SESSION *our_ssl_sessionid;
- void *old_ssl_sessionid = NULL;
-
- our_ssl_sessionid = SSL_get1_session(BACKEND->handle);
-
- /* SSL_get1_session() will increment the reference count and the session
- will stay in memory until explicitly freed with SSL_SESSION_free(3),
- regardless of its state. */
-
- Curl_ssl_sessionid_lock(conn);
- incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
- sockindex));
- if(incache) {
- if(old_ssl_sessionid != our_ssl_sessionid) {
- infof(data, "old SSL session ID is stale, removing\n");
- Curl_ssl_delsessionid(conn, old_ssl_sessionid);
- incache = FALSE;
- }
- }
-
- if(!incache) {
- result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
- 0 /* unknown size */, sockindex);
- if(result) {
- Curl_ssl_sessionid_unlock(conn);
- failf(data, "failed to store ssl session");
- return result;
- }
- }
- else {
- /* Session was incache, so refcount already incremented earlier.
- * Avoid further increments with each SSL_get1_session() call.
- * This does not free the session as refcount remains > 0
- */
- SSL_SESSION_free(our_ssl_sessionid);
- }
- Curl_ssl_sessionid_unlock(conn);
- }
-
/*
* We check certificates to authenticate the server; otherwise we risk
* man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to
@@ -3709,7 +3773,7 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
static size_t Curl_ossl_version(char *buffer, size_t size)
{
#ifdef OPENSSL_IS_BORINGSSL
- return snprintf(buffer, size, OSSL_PACKAGE);
+ return msnprintf(buffer, size, OSSL_PACKAGE);
#else /* OPENSSL_IS_BORINGSSL */
char sub[3];
unsigned long ssleay_value;
@@ -3736,12 +3800,12 @@ static size_t Curl_ossl_version(char *buffer, size_t size)
sub[0]='\0';
}
- return snprintf(buffer, size, "%s/%lx.%lx.%lx%s",
- OSSL_PACKAGE,
- (ssleay_value>>28)&0xf,
- (ssleay_value>>20)&0xff,
- (ssleay_value>>12)&0xff,
- sub);
+ return msnprintf(buffer, size, "%s/%lx.%lx.%lx%s",
+ OSSL_PACKAGE,
+ (ssleay_value>>28)&0xf,
+ (ssleay_value>>20)&0xff,
+ (ssleay_value>>12)&0xff,
+ sub);
#endif /* OPENSSL_IS_BORINGSSL */
}
diff --git a/libs/libcurl/src/vtls/polarssl.c b/libs/libcurl/src/vtls/polarssl.c
index 27af0ccf3e..6ecabe94b5 100644
--- a/libs/libcurl/src/vtls/polarssl.c
+++ b/libs/libcurl/src/vtls/polarssl.c
@@ -497,7 +497,7 @@ polarssl_connect_step2(struct connectdata *conn,
if(ret & BADCERT_REVOKED) {
failf(data, "Cert verify failed: BADCERT_REVOKED");
- return CURLE_SSL_CACERT;
+ return CURLE_PEER_FAILED_VERIFICATION;
}
if(ret & BADCERT_CN_MISMATCH)
@@ -716,9 +716,9 @@ static void Curl_polarssl_session_free(void *ptr)
static size_t Curl_polarssl_version(char *buffer, size_t size)
{
unsigned int version = version_get_number();
- return snprintf(buffer, size, "%s/%d.%d.%d",
- version >= 0x01030A00?"mbedTLS":"PolarSSL",
- version>>24, (version>>16)&0xff, (version>>8)&0xff);
+ return msnprintf(buffer, size, "%s/%d.%d.%d",
+ version >= 0x01030A00?"mbedTLS":"PolarSSL",
+ version>>24, (version>>16)&0xff, (version>>8)&0xff);
}
static CURLcode
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c
index e4426924bc..56fd93e1e5 100644
--- a/libs/libcurl/src/vtls/schannel.c
+++ b/libs/libcurl/src/vtls/schannel.c
@@ -23,9 +23,8 @@
***************************************************************************/
/*
- * Source file for all SChannel-specific code for the TLS/SSL layer. No code
+ * Source file for all Schannel-specific code for the TLS/SSL layer. No code
* but vtls.c should ever call or use these functions.
- *
*/
/*
@@ -196,7 +195,7 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn)
schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
break;
case CURL_SSLVERSION_TLSv1_3:
- failf(data, "Schannel: TLS 1.3 is not yet supported");
+ failf(data, "schannel: TLS 1.3 is not yet supported");
return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -434,7 +433,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT,
VERSION_LESS_THAN_EQUAL)) {
- /* SChannel in Windows XP (OS version 5.1) uses legacy handshakes and
+ /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
algorithms that may not be supported by all servers. */
infof(data, "schannel: WinSSL version is old and may not be able to "
"connect to some servers due to lack of SNI, algorithms, etc.\n");
@@ -1114,13 +1113,68 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
#ifdef HAS_MANUAL_VERIFY_API
if(conn->ssl_config.verifypeer && BACKEND->use_manual_cred_validation) {
- return verify_certificate(conn, sockindex);
+ return Curl_verify_certificate(conn, sockindex);
}
#endif
return CURLE_OK;
}
+static bool
+valid_cert_encoding(const CERT_CONTEXT *cert_context)
+{
+ return (cert_context != NULL) &&
+ ((cert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
+ (cert_context->pbCertEncoded != NULL) &&
+ (cert_context->cbCertEncoded > 0);
+}
+
+typedef bool(*Read_crt_func)(const CERT_CONTEXT *ccert_context, void *arg);
+
+static void
+traverse_cert_store(const CERT_CONTEXT *context, Read_crt_func func,
+ void *arg)
+{
+ const CERT_CONTEXT *current_context = NULL;
+ bool should_continue = true;
+ while(should_continue &&
+ (current_context = CertEnumCertificatesInStore(
+ context->hCertStore,
+ current_context)) != NULL)
+ should_continue = func(current_context, arg);
+
+ if(current_context)
+ CertFreeCertificateContext(current_context);
+}
+
+static bool
+cert_counter_callback(const CERT_CONTEXT *ccert_context, void *certs_count)
+{
+ if(valid_cert_encoding(ccert_context))
+ (*(int *)certs_count)++;
+ return true;
+}
+
+struct Adder_args
+{
+ struct connectdata *conn;
+ CURLcode result;
+ int idx;
+};
+
+static bool
+add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, void *raw_arg)
+{
+ struct Adder_args *args = (struct Adder_args*)raw_arg;
+ args->result = CURLE_OK;
+ if(valid_cert_encoding(ccert_context)) {
+ const char *beg = (const char *) ccert_context->pbCertEncoded;
+ const char *end = beg + ccert_context->cbCertEncoded;
+ args->result = Curl_extract_certinfo(args->conn, (args->idx)++, beg, end);
+ }
+ return args->result == CURLE_OK;
+}
+
static CURLcode
schannel_connect_step3(struct connectdata *conn, int sockindex)
{
@@ -1230,6 +1284,7 @@ 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);
@@ -1238,15 +1293,15 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
return CURLE_PEER_FAILED_VERIFICATION;
}
- result = Curl_ssl_init_certinfo(data, 1);
- if(!result) {
- if(((ccert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
- (ccert_context->cbCertEncoded > 0)) {
+ traverse_cert_store(ccert_context, cert_counter_callback, &certs_count);
- const char *beg = (const char *) ccert_context->pbCertEncoded;
- const char *end = beg + ccert_context->cbCertEncoded;
- result = Curl_extract_certinfo(conn, 0, beg, end);
- }
+ result = Curl_ssl_init_certinfo(data, certs_count);
+ if(!result) {
+ struct Adder_args args;
+ args.conn = conn;
+ args.idx = 0;
+ traverse_cert_store(ccert_context, add_cert_to_certinfo, &args);
+ result = args.result;
}
CertFreeCertificateContext(ccert_context);
if(result)
@@ -1994,7 +2049,7 @@ static void Curl_schannel_cleanup(void)
static size_t Curl_schannel_version(char *buffer, size_t size)
{
- size = snprintf(buffer, size, "WinSSL");
+ size = msnprintf(buffer, size, "WinSSL");
return size;
}
diff --git a/libs/libcurl/src/vtls/schannel.h b/libs/libcurl/src/vtls/schannel.h
index e491bd4318..ee8d7d47ac 100644
--- a/libs/libcurl/src/vtls/schannel.h
+++ b/libs/libcurl/src/vtls/schannel.h
@@ -8,7 +8,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al.
- * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2018, 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
@@ -53,7 +53,7 @@
extern const struct Curl_ssl Curl_ssl_schannel;
-CURLcode verify_certificate(struct connectdata *conn, int sockindex);
+CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex);
/* structs to expose only in schannel.c and schannel_verify.c */
#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c
index 2516f56657..8b21624ba4 100644
--- a/libs/libcurl/src/vtls/schannel_verify.c
+++ b/libs/libcurl/src/vtls/schannel_verify.c
@@ -23,7 +23,7 @@
***************************************************************************/
/*
- * Source file for SChannel-specific certificate verification. This code should
+ * Source file for Schannel-specific certificate verification. This code should
* only be invoked by code in schannel.c.
*/
@@ -406,7 +406,7 @@ cleanup:
return result;
}
-CURLcode verify_certificate(struct connectdata *conn, int sockindex)
+CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
{
SECURITY_STATUS status;
struct Curl_easy *data = conn->data;
diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c
index 6af39feab9..5e75f92e99 100644
--- a/libs/libcurl/src/vtls/vtls.c
+++ b/libs/libcurl/src/vtls/vtls.c
@@ -700,7 +700,7 @@ CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
/* sprintf the label and colon */
- snprintf(output, outlen, "%s:", label);
+ msnprintf(output, outlen, "%s:", label);
/* memcpy the value (it might not be zero terminated) */
memcpy(&output[labellen + 1], value, valuelen);
@@ -1170,8 +1170,6 @@ static const struct Curl_ssl Curl_ssl_multi = {
const struct Curl_ssl *Curl_ssl =
#if defined(CURL_WITH_MULTI_SSL)
&Curl_ssl_multi;
-#elif defined(USE_AXTLS)
- &Curl_ssl_axtls;
#elif defined(USE_CYASSL)
&Curl_ssl_cyassl;
#elif defined(USE_DARWINSSL)
@@ -1197,9 +1195,6 @@ const struct Curl_ssl *Curl_ssl =
#endif
static const struct Curl_ssl *available_backends[] = {
-#if defined(USE_AXTLS)
- &Curl_ssl_axtls,
-#endif
#if defined(USE_CYASSL)
&Curl_ssl_cyassl,
#endif
@@ -1318,7 +1313,14 @@ CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
*avail = (const curl_ssl_backend **)&available_backends;
if(Curl_ssl != &Curl_ssl_multi)
- return id == Curl_ssl->info.id ? CURLSSLSET_OK : CURLSSLSET_TOO_LATE;
+ return id == Curl_ssl->info.id ||
+ (name && strcasecompare(name, Curl_ssl->info.name)) ?
+ CURLSSLSET_OK :
+#if defined(CURL_WITH_MULTI_SSL)
+ CURLSSLSET_TOO_LATE;
+#else
+ CURLSSLSET_UNKNOWN_BACKEND;
+#endif
for(i = 0; available_backends[i]; i++) {
if(available_backends[i]->info.id == id ||
diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h
index 5cd11602e7..1f163631f7 100644
--- a/libs/libcurl/src/vtls/vtls.h
+++ b/libs/libcurl/src/vtls/vtls.h
@@ -103,7 +103,6 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
#include "nssg.h" /* NSS versions */
#include "gskit.h" /* Global Secure ToolKit versions */
#include "polarssl.h" /* PolarSSL versions */
-#include "axtls.h" /* axTLS versions */
#include "cyassl.h" /* CyaSSL versions */
#include "schannel.h" /* Schannel SSPI version */
#include "darwinssl.h" /* SecureTransport (Darwin) version */