summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/vtls/openssl.c
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2022-06-10 01:53:35 +0300
committerdartraiden <wowemuh@gmail.com>2022-06-10 02:24:49 +0300
commit39de82f0732a81d4dc96197bab4ca585a52c353a (patch)
tree8755c2bc4e9779166f30484f2d94c97c87e910a5 /libs/libcurl/src/vtls/openssl.c
parent3c5f696829216c7a113f71ff9099178c11817aca (diff)
libcurl: update to 7.83.1
Diffstat (limited to 'libs/libcurl/src/vtls/openssl.c')
-rw-r--r--libs/libcurl/src/vtls/openssl.c303
1 files changed, 175 insertions, 128 deletions
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index f836c63b07..635e9c15e7 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, 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
@@ -91,7 +91,6 @@
#endif
#include "warnless.h"
-#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */
/* The last #include files should be: */
#include "curl_memory.h"
@@ -209,9 +208,17 @@
!defined(OPENSSL_IS_BORINGSSL))
#define HAVE_SSL_CTX_SET_CIPHERSUITES
#define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
-/* SET_EC_CURVES is available under the same preconditions: see
- * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
+#endif
+
+/*
+ * Whether SSL_CTX_set1_curves_list is available.
+ * OpenSSL: supported since 1.0.2, see
+ * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
+ * BoringSSL: supported since 5fd1807d95f7 (committed 2016-09-30)
+ * LibreSSL: since 2.5.3 (April 12, 2017)
*/
+#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) || \
+ defined(OPENSSL_IS_BORINGSSL)
#define HAVE_SSL_CTX_SET_EC_CURVES
#endif
@@ -266,7 +273,7 @@ struct ssl_backend_data {
#endif
};
-static void ossl_associate_connection(struct Curl_easy *data,
+static bool ossl_associate_connection(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
@@ -549,7 +556,7 @@ static CURLcode ossl_seed(struct Curl_easy *data)
}
}
- infof(data, "libcurl is now using a weak random seed!");
+ infof(data, "libcurl is now using a weak random seed");
return (rand_enough() ? CURLE_OK :
CURLE_SSL_CONNECT_ERROR /* confusing error code */);
#endif
@@ -1159,6 +1166,22 @@ int cert_stuff(struct Curl_easy *data,
return 1;
}
+CURLcode Curl_ossl_set_client_cert(struct Curl_easy *data, SSL_CTX *ctx,
+ char *cert_file,
+ const struct curl_blob *cert_blob,
+ const char *cert_type, char *key_file,
+ const struct curl_blob *key_blob,
+ const char *key_type, char *key_passwd)
+{
+ int rv = cert_stuff(data, ctx, cert_file, cert_blob, cert_type, key_file,
+ key_blob, key_type, key_passwd);
+ if(rv != 1) {
+ return CURLE_SSL_CERTPROBLEM;
+ }
+
+ return CURLE_OK;
+}
+
/* returns non-zero on failure */
static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
{
@@ -1432,6 +1455,9 @@ static void ossl_closeone(struct Curl_easy *data,
struct ssl_connect_data *connssl)
{
struct ssl_backend_data *backend = connssl->backend;
+
+ DEBUGASSERT(backend);
+
if(backend->handle) {
char buf[32];
set_logger(conn, data);
@@ -1489,6 +1515,8 @@ static int ossl_shutdown(struct Curl_easy *data,
struct ssl_backend_data *backend = connssl->backend;
int loop = 10;
+ DEBUGASSERT(backend);
+
#ifndef CURL_DISABLE_FTP
/* 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
@@ -1610,54 +1638,26 @@ static void ossl_close_all(struct Curl_easy *data)
/* ====================================================== */
/*
- * Match subjectAltName against the host name. This requires a conversion
- * in CURL_DOES_CONVERSIONS builds.
+ * Match subjectAltName against the host name.
*/
static bool subj_alt_hostcheck(struct Curl_easy *data,
- const char *match_pattern, const char *hostname,
+ const char *match_pattern,
+ size_t matchlen,
+ const char *hostname,
+ size_t hostlen,
const char *dispname)
-#ifdef CURL_DOES_CONVERSIONS
-{
- bool res = FALSE;
-
- /* Curl_cert_hostcheck uses host encoding, but we get ASCII from
- OpenSSl.
- */
- char *match_pattern2 = strdup(match_pattern);
-
- if(match_pattern2) {
- if(Curl_convert_from_network(data, match_pattern2,
- strlen(match_pattern2)) == CURLE_OK) {
- if(Curl_cert_hostcheck(match_pattern2, hostname)) {
- res = TRUE;
- infof(data,
- " subjectAltName: host \"%s\" matched cert's \"%s\"",
- dispname, match_pattern2);
- }
- }
- free(match_pattern2);
- }
- else {
- failf(data,
- "SSL: out of memory when allocating temporary for subjectAltName");
- }
- return res;
-}
-#else
{
#ifdef CURL_DISABLE_VERBOSE_STRINGS
(void)dispname;
(void)data;
#endif
- if(Curl_cert_hostcheck(match_pattern, hostname)) {
+ if(Curl_cert_hostcheck(match_pattern, matchlen, hostname, hostlen)) {
infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"",
dispname, match_pattern);
return TRUE;
}
return FALSE;
}
-#endif
-
/* Quote from RFC2818 section 3.1 "Server Identity"
@@ -1698,6 +1698,7 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
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();
+ size_t hostlen = strlen(hostname);
#ifdef ENABLE_IPV6
if(conn->bits.ipv6_ip &&
@@ -1760,7 +1761,9 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
if((altlen == strlen(altptr)) &&
/* if this isn't true, there was an embedded zero in the name
string and we cannot match it. */
- subj_alt_hostcheck(data, altptr, hostname, dispname)) {
+ subj_alt_hostcheck(data,
+ altptr,
+ altlen, hostname, hostlen, dispname)) {
dnsmatched = TRUE;
}
break;
@@ -1796,17 +1799,17 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
else {
/* we have to look to the last occurrence of a commonName in the
distinguished one to get the most significant one. */
- int j, i = -1;
+ int i = -1;
+ unsigned char *peer_CN = NULL;
+ int peerlen = 0;
/* The following is done because of a bug in 0.9.6b */
-
- unsigned char *nulstr = (unsigned char *)"";
- unsigned char *peer_CN = nulstr;
-
X509_NAME *name = X509_get_subject_name(server_cert);
- if(name)
+ if(name) {
+ int j;
while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0)
i = j;
+ }
/* we have the name entry and we will now convert this to a string
that we can use for comparison. Doing this we support BMPstring,
@@ -1822,19 +1825,21 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
conditional in the future when OpenSSL has been fixed. */
if(tmp) {
if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
- j = ASN1_STRING_length(tmp);
- if(j >= 0) {
- peer_CN = OPENSSL_malloc(j + 1);
+ peerlen = ASN1_STRING_length(tmp);
+ if(peerlen >= 0) {
+ peer_CN = OPENSSL_malloc(peerlen + 1);
if(peer_CN) {
- memcpy(peer_CN, ASN1_STRING_get0_data(tmp), j);
- peer_CN[j] = '\0';
+ memcpy(peer_CN, ASN1_STRING_get0_data(tmp), peerlen);
+ peer_CN[peerlen] = '\0';
}
+ else
+ result = CURLE_OUT_OF_MEMORY;
}
}
else /* not a UTF8 name */
- j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
+ peerlen = ASN1_STRING_to_UTF8(&peer_CN, tmp);
- if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != j)) {
+ if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != peerlen)) {
/* there was a terminating zero before the end of string, this
cannot match and we return failure! */
failf(data, "SSL: illegal cert name field");
@@ -1843,19 +1848,6 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
}
}
- if(peer_CN == nulstr)
- peer_CN = NULL;
- else {
- /* convert peer_CN from UTF8 */
- CURLcode rc = Curl_convert_from_utf8(data, (char *)peer_CN,
- strlen((char *)peer_CN));
- /* Curl_convert_from_utf8 calls failf if unsuccessful */
- if(rc) {
- OPENSSL_free(peer_CN);
- return rc;
- }
- }
-
if(result)
/* error already detected, pass through */
;
@@ -1864,7 +1856,8 @@ CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
"SSL: unable to obtain common name from peer certificate");
result = CURLE_PEER_FAILED_VERIFICATION;
}
- else if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
+ else if(!Curl_cert_hostcheck((const char *)peer_CN,
+ peerlen, hostname, hostlen)) {
failf(data, "SSL: certificate subject name '%s' does not match "
"target host name '%s'", peer_CN, dispname);
result = CURLE_PEER_FAILED_VERIFICATION;
@@ -1898,8 +1891,11 @@ static CURLcode verifystatus(struct Curl_easy *data,
int cert_status, crl_reason;
ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
int ret;
+ long len;
- long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
+ DEBUGASSERT(backend);
+
+ len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
if(!status) {
failf(data, "No OCSP response received");
@@ -1930,6 +1926,11 @@ static CURLcode verifystatus(struct Curl_easy *data,
}
ch = SSL_get_peer_cert_chain(backend->handle);
+ if(!ch) {
+ failf(data, "Could not get peer certificate chain");
+ result = CURLE_SSL_INVALIDCERTSTATUS;
+ goto end;
+ }
st = SSL_CTX_get_cert_store(backend->ctx);
#if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
@@ -2158,7 +2159,10 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
struct connectdata *conn = userp;
struct ssl_connect_data *connssl = &conn->ssl[0];
struct ssl_backend_data *backend = connssl->backend;
- struct Curl_easy *data = backend->logger;
+ struct Curl_easy *data = NULL;
+
+ DEBUGASSERT(backend);
+ data = backend->logger;
if(!conn || !data || !data->set.fdebug ||
(direction != 0 && direction != 1))
@@ -2363,10 +2367,12 @@ set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
case CURL_SSLVERSION_TLSv1_2:
ossl_ssl_version_min = TLS1_2_VERSION;
break;
-#ifdef TLS1_3_VERSION
case CURL_SSLVERSION_TLSv1_3:
+#ifdef TLS1_3_VERSION
ossl_ssl_version_min = TLS1_3_VERSION;
break;
+#else
+ return CURLE_NOT_BUILT_IN;
#endif
}
@@ -2422,6 +2428,8 @@ set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
#ifdef OPENSSL_IS_BORINGSSL
typedef uint32_t ctx_option_t;
+#elif OPENSSL_VERSION_NUMBER >= 0x30000000L
+typedef uint64_t ctx_option_t;
#else
typedef long ctx_option_t;
#endif
@@ -2442,6 +2450,8 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
#ifdef TLS1_3_VERSION
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
+ DEBUGASSERT(backend);
SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
*ctx_options |= SSL_OP_NO_TLSv1_2;
}
@@ -2521,13 +2531,12 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
return 0;
conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx);
- if(!conn)
- return 0;
-
data = (struct Curl_easy *) SSL_get_ex_data(ssl, data_idx);
-
/* The sockindex has been stored as a pointer to an array element */
sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx);
+ if(!conn || !data || !sockindex_ptr)
+ return 0;
+
sockindex = (int)(sockindex_ptr - conn->sock);
isproxy = SSL_get_ex_data(ssl, proxy_idx) ? TRUE : FALSE;
@@ -2653,7 +2662,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#endif
const long int ssl_version = SSL_CONN_CONFIG(version);
#ifdef USE_OPENSSL_SRP
- const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
+ const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(primary.authtype);
#endif
char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
@@ -2664,12 +2673,13 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
(ca_info_blob ? NULL : 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);
+ const char * const ssl_crlfile = SSL_SET_OPTION(primary.CRLfile);
char error_buffer[256];
struct ssl_backend_data *backend = connssl->backend;
bool imported_native_ca = false;
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
+ DEBUGASSERT(backend);
/* Make funny stuff to get random input */
result = ossl_seed(data);
@@ -2736,8 +2746,8 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
implementations is desired."
The "-no_ticket" option was introduced in OpenSSL 0.9.8j. It's a flag to
- disable "rfc4507bis session ticket support". rfc4507bis was later turned
- into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077
+ disable "rfc4507bis session ticket support". rfc4507bis was later turned
+ into the proper RFC5077: https://datatracker.ietf.org/doc/html/rfc5077
The enabled extension concerns the session management. I wonder how often
libcurl stops a connection and then resumes a TLS session. Also, sending
@@ -2840,14 +2850,14 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH);
cur += ALPN_H2_LENGTH;
- infof(data, "ALPN, offering %s", ALPN_H2);
+ infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
}
#endif
protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
cur += ALPN_HTTP_1_1_LENGTH;
- infof(data, "ALPN, offering %s", ALPN_HTTP_1_1);
+ infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
/* expects length prefixed preference ordered list of protocols in wire
* format
@@ -2913,16 +2923,17 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#endif
#ifdef USE_OPENSSL_SRP
- if(ssl_authtype == CURL_TLSAUTH_SRP) {
- char * const ssl_username = SSL_SET_OPTION(username);
-
+ if((ssl_authtype == CURL_TLSAUTH_SRP) &&
+ Curl_allow_auth_to_host(data)) {
+ char * const ssl_username = SSL_SET_OPTION(primary.username);
+ char * const ssl_password = SSL_SET_OPTION(primary.password);
infof(data, "Using TLS-SRP username: %s", 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_password)) {
failf(data, "failed setting SRP password");
return CURLE_BAD_FUNCTION_ARGUMENT;
}
@@ -2942,7 +2953,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
/* 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 */
+ https://datatracker.ietf.org/doc/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);
@@ -3220,7 +3231,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
SSL_free(backend->handle);
backend->handle = SSL_new(backend->ctx);
if(!backend->handle) {
- failf(data, "SSL: couldn't create a context (handle)!");
+ failf(data, "SSL: couldn't create a context (handle)");
return CURLE_OUT_OF_MEMORY;
}
@@ -3243,44 +3254,48 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
(0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
#endif
sni) {
- size_t nlen = strlen(hostname);
- if((long)nlen >= data->set.buffer_size)
- /* this is seriously messed up */
+ char *snihost = Curl_ssl_snihost(data, hostname, NULL);
+ if(!snihost || !SSL_set_tlsext_host_name(backend->handle, snihost)) {
+ failf(data, "Failed set SNI");
return CURLE_SSL_CONNECT_ERROR;
-
- /* RFC 6066 section 3 says the SNI field is case insensitive, but browsers
- send the data lowercase and subsequently there are now numerous servers
- out there that don't work unless the name is lowercased */
- Curl_strntolower(data->state.buffer, hostname, nlen);
- data->state.buffer[nlen] = 0;
- if(!SSL_set_tlsext_host_name(backend->handle, data->state.buffer))
- infof(data, "WARNING: failed to configure server name indication (SNI) "
- "TLS extension");
+ }
}
#endif
- ossl_associate_connection(data, conn, sockindex);
+ if(!ossl_associate_connection(data, conn, sockindex)) {
+ /* Maybe the internal errors of SSL_get_ex_new_index or SSL_set_ex_data */
+ failf(data, "SSL: ossl_associate_connection failed: %s",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
- Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE,
- &ssl_sessionid, NULL, sockindex)) {
- /* we got a session id, use it! */
- if(!SSL_set_session(backend->handle, ssl_sessionid)) {
- Curl_ssl_sessionid_unlock(data);
- failf(data, "SSL: SSL_set_session failed: %s",
- ossl_strerror(ERR_get_error(), error_buffer,
- sizeof(error_buffer)));
- return CURLE_SSL_CONNECT_ERROR;
+ if(SSL_SET_OPTION(primary.sessionid)) {
+ Curl_ssl_sessionid_lock(data);
+ if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE,
+ &ssl_sessionid, NULL, sockindex)) {
+ /* we got a session id, use it! */
+ if(!SSL_set_session(backend->handle, ssl_sessionid)) {
+ Curl_ssl_sessionid_unlock(data);
+ failf(data, "SSL: SSL_set_session failed: %s",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ /* Informational message */
+ infof(data, "SSL re-using session ID");
}
- /* Informational message */
- infof(data, "SSL re-using session ID");
+ Curl_ssl_sessionid_unlock(data);
}
- Curl_ssl_sessionid_unlock(data);
#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;
+ struct ssl_backend_data *proxy_backend;
+ SSL* handle = NULL;
+ proxy_backend = conn->proxy_ssl[sockindex].backend;
+ DEBUGASSERT(proxy_backend);
+ handle = proxy_backend->handle;
DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
DEBUGASSERT(handle != NULL);
DEBUGASSERT(bio != NULL);
@@ -3310,6 +3325,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
|| ssl_connect_2_writing == connssl->connecting_state);
+ DEBUGASSERT(backend);
ERR_clear_error();
@@ -3441,7 +3457,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
unsigned int len;
SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len);
if(len) {
- infof(data, "ALPN, server accepted to use %.*s", len, neg_protocol);
+ infof(data, VTLS_INFOF_ALPN_ACCEPTED_LEN_1STR, len, neg_protocol);
#ifdef USE_HTTP2
if(len == ALPN_H2_LENGTH &&
@@ -3456,7 +3472,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
}
}
else
- infof(data, "ALPN, server did not agree to a protocol");
+ infof(data, VTLS_INFOF_NO_ALPN);
Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
@@ -3571,6 +3587,8 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
BIO *mem;
struct ssl_backend_data *backend = connssl->backend;
+ DEBUGASSERT(backend);
+
sk = SSL_get_peer_cert_chain(backend->handle);
if(!sk) {
return CURLE_OUT_OF_MEMORY;
@@ -3883,6 +3901,8 @@ static CURLcode servercert(struct Curl_easy *data,
BIO *mem = BIO_new(BIO_s_mem());
struct ssl_backend_data *backend = connssl->backend;
+ DEBUGASSERT(backend);
+
if(!mem) {
failf(data,
"BIO_new return NULL, " OSSL_PACKAGE
@@ -3902,7 +3922,7 @@ static CURLcode servercert(struct Curl_easy *data,
if(!strict)
return CURLE_OK;
- failf(data, "SSL: couldn't get peer certificate!");
+ failf(data, "SSL: couldn't get peer certificate");
return CURLE_PEER_FAILED_VERIFICATION;
}
@@ -3942,7 +3962,7 @@ static CURLcode servercert(struct Curl_easy *data,
buffer, sizeof(buffer));
if(rc) {
if(strict)
- failf(data, "SSL: couldn't get X509-issuer name!");
+ failf(data, "SSL: couldn't get X509-issuer name");
result = CURLE_PEER_FAILED_VERIFICATION;
}
else {
@@ -3953,9 +3973,20 @@ static CURLcode servercert(struct Curl_easy *data,
/* e.g. match issuer name with provided issuer certificate */
if(SSL_CONN_CONFIG(issuercert) || SSL_CONN_CONFIG(issuercert_blob)) {
- if(SSL_CONN_CONFIG(issuercert_blob))
+ if(SSL_CONN_CONFIG(issuercert_blob)) {
fp = BIO_new_mem_buf(SSL_CONN_CONFIG(issuercert_blob)->data,
(int)SSL_CONN_CONFIG(issuercert_blob)->len);
+ if(!fp) {
+ failf(data,
+ "BIO_new_mem_buf 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;
+ }
+ }
else {
fp = BIO_new(BIO_s_file());
if(!fp) {
@@ -4049,7 +4080,7 @@ static CURLcode servercert(struct Curl_easy *data,
if(!result && ptr) {
result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
if(result)
- failf(data, "SSL: public key does not match pinned public key!");
+ failf(data, "SSL: public key does not match pinned public key");
}
X509_free(backend->server_cert);
@@ -4222,11 +4253,13 @@ static bool ossl_data_pending(const struct connectdata *conn,
int connindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+ DEBUGASSERT(connssl->backend);
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];
+ DEBUGASSERT(proxyssl->backend);
if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle))
return TRUE;
}
@@ -4253,6 +4286,8 @@ static ssize_t ossl_send(struct Curl_easy *data,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
+ DEBUGASSERT(backend);
+
ERR_clear_error();
memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
@@ -4332,6 +4367,8 @@ static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
struct ssl_connect_data *connssl = &conn->ssl[num];
struct ssl_backend_data *backend = connssl->backend;
+ DEBUGASSERT(backend);
+
ERR_clear_error();
buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
@@ -4531,20 +4568,22 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl,
{
/* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
struct ssl_backend_data *backend = connssl->backend;
+ DEBUGASSERT(backend);
return info == CURLINFO_TLS_SESSION ?
(void *)backend->ctx : (void *)backend->handle;
}
-static void ossl_associate_connection(struct Curl_easy *data,
+static bool ossl_associate_connection(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
+ DEBUGASSERT(backend);
/* If we don't have SSL context, do nothing. */
if(!backend->handle)
- return;
+ return FALSE;
if(SSL_SET_OPTION(primary.sessionid)) {
int data_idx = ossl_get_ssl_data_index();
@@ -4554,19 +4593,26 @@ static void ossl_associate_connection(struct Curl_easy *data,
if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 &&
proxy_idx >= 0) {
+ int data_status, conn_status, sockindex_status, proxy_status;
+
/* 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, data_idx, data);
- SSL_set_ex_data(backend->handle, connectdata_idx, conn);
- SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex);
+ data_status = SSL_set_ex_data(backend->handle, data_idx, data);
+ conn_status = SSL_set_ex_data(backend->handle, connectdata_idx, conn);
+ sockindex_status = SSL_set_ex_data(backend->handle, sockindex_idx,
+ conn->sock + sockindex);
#ifndef CURL_DISABLE_PROXY
- SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1:
- NULL);
+ proxy_status = SSL_set_ex_data(backend->handle, proxy_idx,
+ SSL_IS_PROXY() ? (void *) 1 : NULL);
#else
- SSL_set_ex_data(backend->handle, proxy_idx, NULL);
+ proxy_status = SSL_set_ex_data(backend->handle, proxy_idx, NULL);
#endif
+ if(data_status && conn_status && sockindex_status && proxy_status)
+ return TRUE;
}
+ return FALSE;
}
+ return TRUE;
}
/*
@@ -4583,6 +4629,7 @@ static void ossl_disassociate_connection(struct Curl_easy *data,
struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
+ DEBUGASSERT(backend);
/* If we don't have SSL context, do nothing. */
if(!backend->handle)