summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/vtls/openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/vtls/openssl.c')
-rw-r--r--libs/libcurl/src/vtls/openssl.c144
1 files changed, 81 insertions, 63 deletions
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index 784d9f70e0..68b98984b4 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.c
@@ -234,6 +234,8 @@
#endif
struct ssl_backend_data {
+ struct Curl_easy *logger; /* transfer handle to pass trace logs to, only
+ using sockindex 0 */
/* these ones requires specific SSL-types */
SSL_CTX* ctx;
SSL* handle;
@@ -391,12 +393,23 @@ static int ossl_get_ssl_conn_index(void)
*/
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);
+ static int sockindex_index = -1;
+ if(sockindex_index < 0) {
+ sockindex_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
}
- return ssl_ex_data_sockindex_index;
+ return sockindex_index;
+}
+
+/* Return an extra data index for proxy boolean.
+ * This index can be used with SSL_get_ex_data() and SSL_set_ex_data().
+ */
+static int ossl_get_proxy_index(void)
+{
+ static int proxy_index = -1;
+ if(proxy_index < 0) {
+ proxy_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+ }
+ return proxy_index;
}
static int passwd_callback(char *buf, int num, int encrypting,
@@ -1172,7 +1185,7 @@ static int ossl_init(void)
/* Initialize the extra data indexes */
if(ossl_get_ssl_data_index() < 0 || ossl_get_ssl_conn_index() < 0 ||
- ossl_get_ssl_sockindex_index() < 0)
+ ossl_get_ssl_sockindex_index() < 0 || ossl_get_proxy_index() < 0)
return 0;
return 1;
@@ -1356,10 +1369,16 @@ static struct curl_slist *ossl_engines_list(struct Curl_easy *data)
return list;
}
-static void ossl_closeone(struct ssl_connect_data *connssl)
+#define set_logger(conn, data) \
+ conn->ssl[0].backend->logger = data
+
+static void ossl_closeone(struct Curl_easy *data,
+ struct connectdata *conn,
+ struct ssl_connect_data *connssl)
{
struct ssl_backend_data *backend = connssl->backend;
if(backend->handle) {
+ set_logger(conn, data);
(void)SSL_shutdown(backend->handle);
SSL_set_connect_state(backend->handle);
@@ -1378,10 +1397,9 @@ static void ossl_closeone(struct ssl_connect_data *connssl)
static void ossl_close(struct Curl_easy *data, struct connectdata *conn,
int sockindex)
{
- (void) data;
- ossl_closeone(&conn->ssl[sockindex]);
+ ossl_closeone(data, conn, &conn->ssl[sockindex]);
#ifndef CURL_DISABLE_PROXY
- ossl_closeone(&conn->proxy_ssl[sockindex]);
+ ossl_closeone(data, conn, &conn->proxy_ssl[sockindex]);
#endif
}
@@ -2055,25 +2073,24 @@ static const char *tls_rt_type(int type)
}
}
-
/*
* Our callback from the SSL/TLS layers.
*/
-static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
- const void *buf, size_t len, SSL *ssl,
- void *userp)
+static void ossl_trace(int direction, int ssl_ver, int content_type,
+ const void *buf, size_t len, SSL *ssl,
+ void *userp)
{
- struct Curl_easy *data;
char unknown[32];
const char *verstr = NULL;
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;
- if(!conn || !conn->data || !conn->data->set.fdebug ||
+ if(!conn || !data || !data->set.fdebug ||
(direction != 0 && direction != 1))
return;
- data = conn->data;
-
switch(ssl_ver) {
#ifdef SSL2_VERSION /* removed in recent versions */
case SSL2_VERSION:
@@ -2222,7 +2239,7 @@ select_next_proto_cb(SSL *ssl,
(void)ssl;
#ifdef USE_NGHTTP2
- if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+ if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
!select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID,
NGHTTP2_PROTO_VERSION_ID_LEN)) {
infof(data, "NPN, negotiated HTTP2 (%s)\n",
@@ -2248,35 +2265,6 @@ select_next_proto_cb(SSL *ssl,
}
#endif /* HAS_NPN */
-#ifndef CURL_DISABLE_VERBOSE_STRINGS
-static const char *
-get_ssl_version_txt(SSL *ssl)
-{
- if(!ssl)
- return "";
-
- switch(SSL_version(ssl)) {
-#ifdef TLS1_3_VERSION
- case TLS1_3_VERSION:
- return "TLSv1.3";
-#endif
-#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
- case TLS1_2_VERSION:
- return "TLSv1.2";
- case TLS1_1_VERSION:
- return "TLSv1.1";
-#endif
- case TLS1_VERSION:
- return "TLSv1.0";
- case SSL3_VERSION:
- return "SSLv3";
- case SSL2_VERSION:
- return "SSLv2";
- }
- return "unknown";
-}
-#endif
-
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
static CURLcode
set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
@@ -2455,8 +2443,10 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
int data_idx = ossl_get_ssl_data_index();
int connectdata_idx = ossl_get_ssl_conn_index();
int sockindex_idx = ossl_get_ssl_sockindex_index();
+ int proxy_idx = ossl_get_proxy_index();
+ bool isproxy;
- if(data_idx < 0 || connectdata_idx < 0 || sockindex_idx < 0)
+ if(data_idx < 0 || connectdata_idx < 0 || sockindex_idx < 0 || proxy_idx < 0)
return 0;
conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx);
@@ -2469,13 +2459,18 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx);
sockindex = (int)(sockindex_ptr - conn->sock);
+ isproxy = SSL_get_ex_data(ssl, proxy_idx) ? TRUE : FALSE;
+
if(SSL_SET_OPTION(primary.sessionid)) {
bool incache;
void *old_ssl_sessionid = NULL;
Curl_ssl_sessionid_lock(data);
- incache = !(Curl_ssl_getsessionid(data, conn, &old_ssl_sessionid, NULL,
- sockindex));
+ if(isproxy)
+ incache = FALSE;
+ else
+ incache = !(Curl_ssl_getsessionid(data, conn, isproxy,
+ &old_ssl_sessionid, NULL, sockindex));
if(incache) {
if(old_ssl_sessionid != ssl_sessionid) {
infof(data, "old SSL session ID is stale, removing\n");
@@ -2485,8 +2480,8 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
}
if(!incache) {
- if(!Curl_ssl_addsessionid(data, conn, ssl_sessionid,
- 0 /* unknown size */, sockindex)) {
+ if(!Curl_ssl_addsessionid(data, conn, isproxy, ssl_sessionid,
+ 0 /* unknown size */, sockindex)) {
/* the session has been put into the session cache */
res = 1;
}
@@ -2609,8 +2604,9 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#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(backend->ctx, ossl_trace);
SSL_CTX_set_msg_callback_arg(backend->ctx, conn);
+ set_logger(conn, data);
}
#endif
@@ -2749,7 +2745,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
unsigned char protocols[128];
#ifdef USE_NGHTTP2
- if(data->set.httpversion >= CURL_HTTP_VERSION_2
+ if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
#endif
@@ -2771,7 +2767,10 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
/* expects length prefixed preference ordered list of protocols in wire
* format
*/
- SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur);
+ if(SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur)) {
+ failf(data, "Error setting ALPN");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
}
#endif
@@ -3212,17 +3211,27 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
int data_idx = ossl_get_ssl_data_index();
int connectdata_idx = ossl_get_ssl_conn_index();
int sockindex_idx = ossl_get_ssl_sockindex_index();
+ int proxy_idx = ossl_get_proxy_index();
- if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0) {
+ if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 &&
+ proxy_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, data_idx, data);
SSL_set_ex_data(backend->handle, connectdata_idx, conn);
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);
+#else
+ SSL_set_ex_data(backend->handle, proxy_idx, NULL);
+#endif
+
}
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, &ssl_sessionid, NULL, sockindex)) {
+ 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);
@@ -3380,7 +3389,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
/* Informational message */
infof(data, "SSL connection using %s / %s\n",
- get_ssl_version_txt(backend->handle),
+ SSL_get_version(backend->handle),
SSL_get_cipher(backend->handle));
#ifdef HAS_ALPN
@@ -3515,6 +3524,12 @@ typedef size_t numcert_t;
typedef int numcert_t;
#endif
+#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
+#define OSSL3_CONST const
+#else
+#define OSSL3_CONST
+#endif
+
static CURLcode get_cert_chain(struct Curl_easy *data,
struct ssl_connect_data *connssl)
{
@@ -3622,7 +3637,7 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
switch(pktype) {
case EVP_PKEY_RSA:
{
- RSA *rsa;
+ OSSL3_CONST RSA *rsa;
#ifdef HAVE_OPAQUE_EVP_PKEY
rsa = EVP_PKEY_get0_RSA(pubkey);
#else
@@ -3652,7 +3667,7 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
case EVP_PKEY_DSA:
{
#ifndef OPENSSL_NO_DSA
- DSA *dsa;
+ OSSL3_CONST DSA *dsa;
#ifdef HAVE_OPAQUE_EVP_PKEY
dsa = EVP_PKEY_get0_DSA(pubkey);
#else
@@ -3684,7 +3699,7 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
}
case EVP_PKEY_DH:
{
- DH *dh;
+ OSSL3_CONST DH *dh;
#ifdef HAVE_OPAQUE_EVP_PKEY
dh = EVP_PKEY_get0_DH(pubkey);
#else
@@ -3965,7 +3980,7 @@ static CURLcode servercert(struct Curl_easy *data,
result = CURLE_OK;
ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(!result && ptr) {
result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
if(result)
@@ -4176,6 +4191,7 @@ static ssize_t ossl_send(struct Curl_easy *data,
ERR_clear_error();
memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
+ set_logger(conn, data);
rc = SSL_write(backend->handle, mem, memlen);
if(rc <= 0) {
@@ -4254,6 +4270,7 @@ static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */
ERR_clear_error();
buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
+ set_logger(conn, data);
nread = (ssize_t)SSL_read(backend->handle, buf, buffsize);
if(nread <= 0) {
/* failed SSL_read */
@@ -4477,6 +4494,7 @@ const struct Curl_ssl Curl_ssl_openssl = {
ossl_cert_status_request, /* cert_status_request */
ossl_connect, /* connect */
ossl_connect_nonblocking, /* connect_nonblocking */
+ Curl_ssl_getsock, /* getsock */
ossl_get_internals, /* get_internals */
ossl_close, /* close_one */
ossl_close_all, /* close_all */