aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/curl/lib/vtls
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-04-08 22:37:27 +0300
committershadchin <shadchin@yandex-team.ru>2022-04-08 22:37:27 +0300
commit1331b4eeb3379e6b60ee2bdec44c6394ee34be24 (patch)
tree57a80b36f47b10b54b9e4acec72661fccfafee5f /contrib/libs/curl/lib/vtls
parent6886c6a225f5b54d62c38bac5b53af7dcaa09fd6 (diff)
downloadydb-1331b4eeb3379e6b60ee2bdec44c6394ee34be24.tar.gz
CONTRIB-2513 Update contrib/libs/curl to 7.76.1
ref:6ca4bf15fd9dd0eb27cbc38bcd575b8251b98a4b
Diffstat (limited to 'contrib/libs/curl/lib/vtls')
-rw-r--r--contrib/libs/curl/lib/vtls/bearssl.c11
-rw-r--r--contrib/libs/curl/lib/vtls/gskit.c5
-rw-r--r--contrib/libs/curl/lib/vtls/gtls.c56
-rw-r--r--contrib/libs/curl/lib/vtls/mbedtls.c19
-rw-r--r--contrib/libs/curl/lib/vtls/mesalink.c15
-rw-r--r--contrib/libs/curl/lib/vtls/nss.c12
-rw-r--r--contrib/libs/curl/lib/vtls/openssl.c252
-rw-r--r--contrib/libs/curl/lib/vtls/rustls.c560
-rw-r--r--contrib/libs/curl/lib/vtls/rustls.h33
-rw-r--r--contrib/libs/curl/lib/vtls/schannel.c19
-rw-r--r--contrib/libs/curl/lib/vtls/schannel_verify.c2
-rw-r--r--contrib/libs/curl/lib/vtls/sectransp.c22
-rw-r--r--contrib/libs/curl/lib/vtls/vtls.c41
-rw-r--r--contrib/libs/curl/lib/vtls/vtls.h19
-rw-r--r--contrib/libs/curl/lib/vtls/wolfssl.c56
15 files changed, 872 insertions, 250 deletions
diff --git a/contrib/libs/curl/lib/vtls/bearssl.c b/contrib/libs/curl/lib/vtls/bearssl.c
index 29b08c0e6d..a63056d4ef 100644
--- a/contrib/libs/curl/lib/vtls/bearssl.c
+++ b/contrib/libs/curl/lib/vtls/bearssl.c
@@ -375,7 +375,8 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
void *session;
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, &session, NULL, sockindex)) {
+ if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE,
+ &session, NULL, sockindex)) {
br_ssl_engine_set_session_parameters(&backend->ctx.eng, session);
infof(data, "BearSSL: re-using session ID\n");
}
@@ -390,7 +391,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
*/
#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
@@ -571,10 +572,13 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data,
br_ssl_engine_get_session_parameters(&backend->ctx.eng, session);
Curl_ssl_sessionid_lock(data);
incache = !(Curl_ssl_getsessionid(data, conn,
+ SSL_IS_PROXY() ? TRUE : FALSE,
&oldsession, NULL, sockindex));
if(incache)
Curl_ssl_delsessionid(data, oldsession);
- ret = Curl_ssl_addsessionid(data, conn, session, 0, sockindex);
+ ret = Curl_ssl_addsessionid(data, conn,
+ SSL_IS_PROXY() ? TRUE : FALSE,
+ session, 0, sockindex);
Curl_ssl_sessionid_unlock(data);
if(ret) {
free(session);
@@ -855,6 +859,7 @@ const struct Curl_ssl Curl_ssl_bearssl = {
Curl_none_cert_status_request,
bearssl_connect,
bearssl_connect_nonblocking,
+ Curl_ssl_getsock,
bearssl_get_internals,
bearssl_close,
Curl_none_close_all,
diff --git a/contrib/libs/curl/lib/vtls/gskit.c b/contrib/libs/curl/lib/vtls/gskit.c
index 81c258a0fd..4b69dc7e70 100644
--- a/contrib/libs/curl/lib/vtls/gskit.c
+++ b/contrib/libs/curl/lib/vtls/gskit.c
@@ -610,7 +610,7 @@ static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data,
}
-static ssize_t gskit_send(struct connectdata *conn, int sockindex,
+static ssize_t gskit_send(struct Curl_easy *data, int sockindex,
const void *mem, size_t len, CURLcode *curlcode)
{
struct connectdata *conn = data->conn;
@@ -700,7 +700,6 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
gsk_handle envir;
CURLcode result;
- int rc;
const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert);
@@ -1037,7 +1036,7 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data,
/* Check pinned public key. */
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) {
curl_X509certificate x509;
curl_asn1Element *p;
diff --git a/contrib/libs/curl/lib/vtls/gtls.c b/contrib/libs/curl/lib/vtls/gtls.c
index 18be78ca4c..94c3f17c63 100644
--- a/contrib/libs/curl/lib/vtls/gtls.c
+++ b/contrib/libs/curl/lib/vtls/gtls.c
@@ -35,14 +35,8 @@
#include <gnutls/abstract.h>
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
-
-#ifdef USE_GNUTLS_NETTLE
#include <gnutls/crypto.h>
-#include <nettle/md5.h>
#include <nettle/sha2.h>
-#else
-#include <gcrypt.h>
-#endif
#include "urldata.h"
#include "sendf.h"
@@ -618,7 +612,7 @@ gtls_connect_step1(struct Curl_easy *data,
gnutls_datum_t protocols[2];
#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
@@ -733,6 +727,7 @@ gtls_connect_step1(struct Curl_easy *data,
Curl_ssl_sessionid_lock(data);
if(!Curl_ssl_getsessionid(data, conn,
+ SSL_IS_PROXY() ? TRUE : FALSE,
&ssl_sessionid, &ssl_idsize, sockindex)) {
/* we got a session id, use it! */
gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
@@ -1184,7 +1179,7 @@ gtls_connect_step3(struct Curl_easy *data,
}
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(ptr) {
result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
if(result != CURLE_OK) {
@@ -1292,8 +1287,9 @@ gtls_connect_step3(struct Curl_easy *data,
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
Curl_ssl_sessionid_lock(data);
- incache = !(Curl_ssl_getsessionid(data, conn, &ssl_sessionid, NULL,
- sockindex));
+ incache = !(Curl_ssl_getsessionid(data, conn,
+ SSL_IS_PROXY() ? TRUE : FALSE,
+ &ssl_sessionid, NULL, sockindex));
if(incache) {
/* there was one before in the cache, so instead of risking that the
previous one was rejected, we just kill that and store the new */
@@ -1301,8 +1297,10 @@ gtls_connect_step3(struct Curl_easy *data,
}
/* store this session id */
- result = Curl_ssl_addsessionid(data, conn, connect_sessionid,
- connect_idsize, sockindex);
+ result = Curl_ssl_addsessionid(data, conn,
+ SSL_IS_PROXY() ? TRUE : FALSE,
+ connect_sessionid, connect_idsize,
+ sockindex);
Curl_ssl_sessionid_unlock(data);
if(result) {
free(connect_sessionid);
@@ -1583,39 +1581,14 @@ static size_t gtls_version(char *buffer, size_t size)
return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
}
-#ifndef USE_GNUTLS_NETTLE
-static int gtls_seed(struct Curl_easy *data)
-{
- /* we have the "SSL is seeded" boolean static to prevent multiple
- time-consuming seedings in vain */
- static bool ssl_seeded = FALSE;
-
- /* Quickly add a bit of entropy */
- gcry_fast_random_poll();
-
- if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
- data->set.str[STRING_SSL_EGDSOCKET]) {
- ssl_seeded = TRUE;
- }
- return 0;
-}
-#endif
-
/* data might be NULL! */
static CURLcode gtls_random(struct Curl_easy *data,
unsigned char *entropy, size_t length)
{
-#if defined(USE_GNUTLS_NETTLE)
int rc;
(void)data;
rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
return rc?CURLE_FAILED_INIT:CURLE_OK;
-#elif defined(USE_GNUTLS)
- if(data)
- gtls_seed(data); /* Initiate the seed if not already done */
- gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
-#endif
- return CURLE_OK;
}
static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */
@@ -1623,18 +1596,10 @@ static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */
unsigned char *sha256sum, /* output */
size_t sha256len)
{
-#if defined(USE_GNUTLS_NETTLE)
struct sha256_ctx SHA256pw;
sha256_init(&SHA256pw);
sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
-#elif defined(USE_GNUTLS)
- gcry_md_hd_t SHA256pw;
- gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0);
- gcry_md_write(SHA256pw, tmp, tmplen);
- memcpy(sha256sum, gcry_md_read(SHA256pw, 0), sha256len);
- gcry_md_close(SHA256pw);
-#endif
return CURLE_OK;
}
@@ -1671,6 +1636,7 @@ const struct Curl_ssl Curl_ssl_gnutls = {
gtls_cert_status_request, /* cert_status_request */
gtls_connect, /* connect */
gtls_connect_nonblocking, /* connect_nonblocking */
+ Curl_ssl_getsock, /* getsock */
gtls_get_internals, /* get_internals */
gtls_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/contrib/libs/curl/lib/vtls/mbedtls.c b/contrib/libs/curl/lib/vtls/mbedtls.c
index 49adeef10f..b7df301ef0 100644
--- a/contrib/libs/curl/lib/vtls/mbedtls.c
+++ b/contrib/libs/curl/lib/vtls/mbedtls.c
@@ -463,7 +463,9 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
void *old_session = NULL;
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, &old_session, NULL, sockindex)) {
+ if(!Curl_ssl_getsessionid(data, conn,
+ SSL_IS_PROXY() ? TRUE : FALSE,
+ &old_session, NULL, sockindex)) {
ret = mbedtls_ssl_set_session(&backend->ssl, old_session);
if(ret) {
Curl_ssl_sessionid_unlock(data);
@@ -495,7 +497,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
if(conn->bits.tls_enable_alpn) {
const char **p = &backend->protocols[0];
#ifdef USE_NGHTTP2
- if(data->set.httpversion >= CURL_HTTP_VERSION_2)
+ if(data->state.httpwant >= CURL_HTTP_VERSION_2)
*p++ = NGHTTP2_PROTO_VERSION_ID;
#endif
*p++ = ALPN_HTTP_1_1;
@@ -550,10 +552,10 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
#ifndef CURL_DISABLE_PROXY
const char * const pinnedpubkey = SSL_IS_PROXY() ?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
#else
const char * const pinnedpubkey =
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
#endif
conn->recv[sockindex] = mbed_recv;
@@ -724,6 +726,7 @@ mbed_connect_step3(struct Curl_easy *data, struct connectdata *conn,
int ret;
mbedtls_ssl_session *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
+ bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session));
if(!our_ssl_sessionid)
@@ -742,11 +745,12 @@ mbed_connect_step3(struct Curl_easy *data, struct connectdata *conn,
/* If there's already a matching session in the cache, delete it */
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, &old_ssl_sessionid, NULL, sockindex))
+ if(!Curl_ssl_getsessionid(data, conn, isproxy, &old_ssl_sessionid, NULL,
+ sockindex))
Curl_ssl_delsessionid(data, old_ssl_sessionid);
- retcode = Curl_ssl_addsessionid(data, conn,
- our_ssl_sessionid, 0, sockindex);
+ retcode = Curl_ssl_addsessionid(data, conn, isproxy, our_ssl_sessionid,
+ 0, sockindex);
Curl_ssl_sessionid_unlock(data);
if(retcode) {
mbedtls_ssl_session_free(our_ssl_sessionid);
@@ -1100,6 +1104,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
Curl_none_cert_status_request, /* cert_status_request */
mbedtls_connect, /* connect */
mbedtls_connect_nonblocking, /* connect_nonblocking */
+ Curl_ssl_getsock, /* getsock */
mbedtls_get_internals, /* get_internals */
mbedtls_close, /* close_one */
mbedtls_close_all, /* close_all */
diff --git a/contrib/libs/curl/lib/vtls/mesalink.c b/contrib/libs/curl/lib/vtls/mesalink.c
index 19450522e2..5df5253b1e 100644
--- a/contrib/libs/curl/lib/vtls/mesalink.c
+++ b/contrib/libs/curl/lib/vtls/mesalink.c
@@ -261,7 +261,9 @@ mesalink_connect_step1(struct Curl_easy *data,
void *ssl_sessionid = NULL;
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);
@@ -345,13 +347,14 @@ mesalink_connect_step3(struct connectdata *conn, int sockindex)
bool incache;
SSL_SESSION *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
+ bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
our_ssl_sessionid = SSL_get_session(BACKEND->handle);
Curl_ssl_sessionid_lock(data);
incache =
- !(Curl_ssl_getsessionid(data, conn,
- &old_ssl_sessionid, NULL, sockindex));
+ !(Curl_ssl_getsessionid(data, conn, isproxy, &old_ssl_sessionid, NULL,
+ sockindex));
if(incache) {
if(old_ssl_sessionid != our_ssl_sessionid) {
infof(data, "old SSL session ID is stale, removing\n");
@@ -361,8 +364,9 @@ mesalink_connect_step3(struct connectdata *conn, int sockindex)
}
if(!incache) {
- result = Curl_ssl_addsessionid(
- data, conn, our_ssl_sessionid, 0 /* unknown size */, sockindex);
+ result =
+ Curl_ssl_addsessionid(data, conn, isproxy, our_ssl_sessionid, 0,
+ sockindex);
if(result) {
Curl_ssl_sessionid_unlock(data);
failf(data, "failed to store ssl session");
@@ -654,6 +658,7 @@ const struct Curl_ssl Curl_ssl_mesalink = {
Curl_none_cert_status_request, /* cert_status_request */
mesalink_connect, /* connect */
mesalink_connect_nonblocking, /* connect_nonblocking */
+ Curl_ssl_getsock, /* getsock */
mesalink_get_internals, /* get_internals */
mesalink_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/contrib/libs/curl/lib/vtls/nss.c b/contrib/libs/curl/lib/vtls/nss.c
index e9b350b82e..dc252e8c93 100644
--- a/contrib/libs/curl/lib/vtls/nss.c
+++ b/contrib/libs/curl/lib/vtls/nss.c
@@ -542,7 +542,6 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
if(!result && !cacert) {
/* we have successfully loaded a client certificate */
- CERTCertificate *cert;
char *nickname = NULL;
char *n = strrchr(filename, '/');
if(n)
@@ -554,7 +553,7 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
* <https://bugzilla.redhat.com/733685>. */
nickname = aprintf("PEM Token #1:%s", n);
if(nickname) {
- cert = PK11_FindCertFromNickname(nickname, NULL);
+ CERTCertificate *cert = PK11_FindCertFromNickname(nickname, NULL);
if(cert)
CERT_DestroyCertificate(cert);
@@ -957,7 +956,6 @@ static CURLcode display_conn_info(struct Curl_easy *data, PRFileDesc *sock)
CERTCertificate *cert2;
CERTCertificate *cert3;
PRTime now;
- int i;
if(SSL_GetChannelInfo(sock, &channel, sizeof(channel)) ==
SECSuccess && channel.length == sizeof(channel) &&
@@ -978,8 +976,8 @@ static CURLcode display_conn_info(struct Curl_easy *data, PRFileDesc *sock)
}
else {
/* Count certificates in chain. */
+ int i = 1;
now = PR_Now();
- i = 1;
if(!cert->isRoot) {
cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
while(cert2) {
@@ -1782,12 +1780,11 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
struct Curl_easy *data,
CURLcode curlerr)
{
- PRErrorCode err = 0;
struct ssl_backend_data *backend = connssl->backend;
if(is_nss_error(curlerr)) {
/* read NSPR error code */
- err = PR_GetError();
+ PRErrorCode err = PR_GetError();
if(is_cc_error(err))
curlerr = CURLE_SSL_CERTPROBLEM;
@@ -2083,7 +2080,7 @@ static CURLcode nss_setup_connect(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
@@ -2435,6 +2432,7 @@ const struct Curl_ssl Curl_ssl_nss = {
nss_cert_status_request, /* cert_status_request */
nss_connect, /* connect */
nss_connect_nonblocking, /* connect_nonblocking */
+ Curl_ssl_getsock, /* getsock */
nss_get_internals, /* get_internals */
nss_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/contrib/libs/curl/lib/vtls/openssl.c b/contrib/libs/curl/lib/vtls/openssl.c
index 784d9f70e0..6583300b3c 100644
--- a/contrib/libs/curl/lib/vtls/openssl.c
+++ b/contrib/libs/curl/lib/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,
@@ -587,11 +600,16 @@ static bool is_pkcs11_uri(const char *string)
static CURLcode ossl_set_engine(struct Curl_easy *data, const char *engine);
static int
-SSL_CTX_use_certificate_bio(SSL_CTX *ctx, BIO *in, int type,
- const char *key_passwd)
+SSL_CTX_use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob,
+ int type, const char *key_passwd)
{
int ret = 0;
X509 *x = NULL;
+ /* the typecast of blob->len is fine since it is guaranteed to never be
+ larger than CURL_MAX_INPUT_LENGTH */
+ BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len));
+ if(!in)
+ return CURLE_OUT_OF_MEMORY;
if(type == SSL_FILETYPE_ASN1) {
/* j = ERR_R_ASN1_LIB; */
@@ -615,15 +633,19 @@ SSL_CTX_use_certificate_bio(SSL_CTX *ctx, BIO *in, int type,
ret = SSL_CTX_use_certificate(ctx, x);
end:
X509_free(x);
+ BIO_free(in);
return ret;
}
static int
-SSL_CTX_use_PrivateKey_bio(SSL_CTX *ctx, BIO* in, int type,
- const char *key_passwd)
+SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob,
+ int type, const char *key_passwd)
{
int ret = 0;
EVP_PKEY *pkey = NULL;
+ BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len));
+ if(!in)
+ return CURLE_OUT_OF_MEMORY;
if(type == SSL_FILETYPE_PEM)
pkey = PEM_read_bio_PrivateKey(in, NULL, passwd_callback,
@@ -641,11 +663,12 @@ SSL_CTX_use_PrivateKey_bio(SSL_CTX *ctx, BIO* in, int type,
ret = SSL_CTX_use_PrivateKey(ctx, pkey);
EVP_PKEY_free(pkey);
end:
+ BIO_free(in);
return ret;
}
static int
-SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO* in,
+SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob,
const char *key_passwd)
{
/* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */
@@ -655,6 +678,9 @@ SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO* in,
int ret = 0;
X509 *x = NULL;
void *passwd_callback_userdata = (void *)key_passwd;
+ BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len));
+ if(!in)
+ return CURLE_OUT_OF_MEMORY;
ERR_clear_error();
@@ -669,7 +695,7 @@ SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO* in,
ret = SSL_CTX_use_certificate(ctx, x);
if(ERR_peek_error() != 0)
- ret = 0;
+ ret = 0;
if(ret) {
X509 *ca;
@@ -701,6 +727,7 @@ SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO* in,
end:
X509_free(x);
+ BIO_free(in);
return ret;
#else
(void)ctx; /* unused */
@@ -714,10 +741,10 @@ static
int cert_stuff(struct Curl_easy *data,
SSL_CTX* ctx,
char *cert_file,
- BIO *cert_bio,
+ const struct curl_blob *cert_blob,
const char *cert_type,
char *key_file,
- BIO* key_bio,
+ const struct curl_blob *key_blob,
const char *key_type,
char *key_passwd)
{
@@ -726,7 +753,7 @@ int cert_stuff(struct Curl_easy *data,
int file_type = do_file_type(cert_type);
- if(cert_file || cert_bio || (file_type == SSL_FILETYPE_ENGINE)) {
+ if(cert_file || cert_blob || (file_type == SSL_FILETYPE_ENGINE)) {
SSL *ssl;
X509 *x509;
int cert_done = 0;
@@ -743,9 +770,9 @@ int cert_stuff(struct Curl_easy *data,
switch(file_type) {
case SSL_FILETYPE_PEM:
/* SSL_CTX_use_certificate_chain_file() only works on PEM files */
- cert_use_result = cert_bio ?
- SSL_CTX_use_certificate_chain_bio(ctx, cert_bio, key_passwd) :
- SSL_CTX_use_certificate_chain_file(ctx, cert_file);
+ cert_use_result = cert_blob ?
+ SSL_CTX_use_certificate_chain_blob(ctx, cert_blob, key_passwd) :
+ SSL_CTX_use_certificate_chain_file(ctx, cert_file);
if(cert_use_result != 1) {
failf(data,
"could not load PEM client certificate, " OSSL_PACKAGE
@@ -762,10 +789,10 @@ int cert_stuff(struct Curl_easy *data,
we use the case above for PEM so this can only be performed with
ASN1 files. */
- cert_use_result = cert_bio ?
- SSL_CTX_use_certificate_bio(ctx, cert_bio,
- file_type, key_passwd) :
- SSL_CTX_use_certificate_file(ctx, cert_file, file_type);
+ cert_use_result = cert_blob ?
+ SSL_CTX_use_certificate_blob(ctx, cert_blob,
+ file_type, key_passwd) :
+ SSL_CTX_use_certificate_file(ctx, cert_file, file_type);
if(cert_use_result != 1) {
failf(data,
"could not load ASN1 client certificate, " OSSL_PACKAGE
@@ -842,13 +869,24 @@ int cert_stuff(struct Curl_easy *data,
case SSL_FILETYPE_PKCS12:
{
- BIO *fp = NULL;
+ BIO *cert_bio = NULL;
PKCS12 *p12 = NULL;
EVP_PKEY *pri;
STACK_OF(X509) *ca = NULL;
- if(!cert_bio) {
- fp = BIO_new(BIO_s_file());
- if(fp == NULL) {
+ if(cert_blob) {
+ cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len));
+ if(cert_bio == NULL) {
+ failf(data,
+ "BIO_new_mem_buf NULL, " OSSL_PACKAGE
+ " error %s",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)) );
+ return 0;
+ }
+ }
+ else {
+ cert_bio = BIO_new(BIO_s_file());
+ if(cert_bio == NULL) {
failf(data,
"BIO_new return NULL, " OSSL_PACKAGE
" error %s",
@@ -857,20 +895,19 @@ int cert_stuff(struct Curl_easy *data,
return 0;
}
- if(BIO_read_filename(fp, cert_file) <= 0) {
+ if(BIO_read_filename(cert_bio, cert_file) <= 0) {
failf(data, "could not open PKCS12 file '%s'", cert_file);
- BIO_free(fp);
+ BIO_free(cert_bio);
return 0;
}
}
- p12 = d2i_PKCS12_bio(cert_bio ? cert_bio : fp, NULL);
- if(fp)
- BIO_free(fp);
+ p12 = d2i_PKCS12_bio(cert_bio, NULL);
+ BIO_free(cert_bio);
if(!p12) {
failf(data, "error reading PKCS12 file '%s'",
- cert_bio ? "(memory blob)" : cert_file);
+ cert_blob ? "(memory blob)" : cert_file);
return 0;
}
@@ -951,9 +988,9 @@ int cert_stuff(struct Curl_easy *data,
return 0;
}
- if((!key_file) && (!key_bio)) {
+ if((!key_file) && (!key_blob)) {
key_file = cert_file;
- key_bio = cert_bio;
+ key_blob = cert_blob;
}
else
file_type = do_file_type(key_type);
@@ -964,8 +1001,8 @@ int cert_stuff(struct Curl_easy *data,
break;
/* FALLTHROUGH */
case SSL_FILETYPE_ASN1:
- cert_use_result = key_bio ?
- SSL_CTX_use_PrivateKey_bio(ctx, key_bio, file_type, key_passwd) :
+ cert_use_result = key_blob ?
+ SSL_CTX_use_PrivateKey_blob(ctx, key_blob, file_type, key_passwd) :
SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type);
if(cert_use_result != 1) {
failf(data, "unable to set private key file: '%s' type %s",
@@ -1172,7 +1209,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 +1393,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 +1421,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 +2097,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 +2263,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 +2289,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 +2467,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 +2483,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 +2504,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 +2628,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 +2769,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,37 +2791,20 @@ 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
if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
- BIO *ssl_cert_bio = NULL;
- BIO *ssl_key_bio = NULL;
- if(ssl_cert_blob) {
- /* the typecast of blob->len is fine since it is guaranteed to never be
- larger than CURL_MAX_INPUT_LENGTH */
- ssl_cert_bio = BIO_new_mem_buf(ssl_cert_blob->data,
- (int)ssl_cert_blob->len);
- if(!ssl_cert_bio)
- result = CURLE_OUT_OF_MEMORY;
- }
- if(!result && SSL_SET_OPTION(key_blob)) {
- ssl_key_bio = BIO_new_mem_buf(SSL_SET_OPTION(key_blob)->data,
- (int)SSL_SET_OPTION(key_blob)->len);
- if(!ssl_key_bio)
- result = CURLE_OUT_OF_MEMORY;
- }
if(!result &&
!cert_stuff(data, backend->ctx,
- ssl_cert, ssl_cert_bio, ssl_cert_type,
- SSL_SET_OPTION(key), ssl_key_bio,
+ ssl_cert, ssl_cert_blob, ssl_cert_type,
+ SSL_SET_OPTION(key), SSL_SET_OPTION(key_blob),
SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd)))
result = CURLE_SSL_CERTPROBLEM;
- if(ssl_cert_bio)
- BIO_free(ssl_cert_bio);
- if(ssl_key_bio)
- BIO_free(ssl_key_bio);
if(result)
/* failf() is already done in cert_stuff() */
return result;
@@ -3212,17 +3215,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 +3393,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 +3528,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 +3641,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 +3671,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 +3703,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 +3984,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 +4195,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 +4274,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 +4498,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 */
diff --git a/contrib/libs/curl/lib/vtls/rustls.c b/contrib/libs/curl/lib/vtls/rustls.c
new file mode 100644
index 0000000000..944a80e706
--- /dev/null
+++ b/contrib/libs/curl/lib/vtls/rustls.c
@@ -0,0 +1,560 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020 - 2021, Jacob Hoffman-Andrews,
+ * <github@hoffman-andrews.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_RUSTLS
+
+#include "curl_printf.h"
+
+#include <errno.h>
+#error #include <crustls.h>
+
+#include "inet_pton.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "vtls.h"
+#include "select.h"
+
+#include "multiif.h"
+
+/* Per https://www.bearssl.org/api1.html, max TLS record size plus max
+ per-record overhead. */
+#define TLSBUF_SIZE (16384 + 325)
+
+struct ssl_backend_data
+{
+ const struct rustls_client_config *config;
+ struct rustls_client_session *session;
+ bool data_pending;
+ uint8_t *tlsbuf;
+};
+
+/* For a given rustls_result error code, return the best-matching CURLcode. */
+static CURLcode map_error(rustls_result r)
+{
+ if(rustls_result_is_cert_error(r)) {
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ switch(r) {
+ case RUSTLS_RESULT_OK:
+ return CURLE_OK;
+ case RUSTLS_RESULT_NULL_PARAMETER:
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+ default:
+ return CURLE_READ_ERROR;
+ }
+}
+
+static bool
+cr_data_pending(const struct connectdata *conn, int sockindex)
+{
+ const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
+ return backend->data_pending;
+}
+
+static CURLcode
+cr_connect(struct Curl_easy *data UNUSED_PARAM,
+ struct connectdata *conn UNUSED_PARAM,
+ int sockindex UNUSED_PARAM)
+{
+ infof(data, "rustls_connect: unimplemented\n");
+ return CURLE_SSL_CONNECT_ERROR;
+}
+
+/*
+ * On each run:
+ * - Read a chunk of bytes from the socket into rustls' TLS input buffer.
+ * - Tell rustls to process any new packets.
+ * - Read out as many plaintext bytes from rustls as possible, until hitting
+ * error, EOF, or EAGAIN/EWOULDBLOCK, or plainbuf/plainlen is filled up.
+ *
+ * It's okay to call this function with plainbuf == NULL and plainlen == 0.
+ * In that case, it will copy bytes from the socket into rustls' TLS input
+ * buffer, and process packets, but won't consume bytes from rustls' plaintext
+ * output buffer.
+ */
+static ssize_t
+cr_recv(struct Curl_easy *data, int sockindex,
+ char *plainbuf, size_t plainlen, CURLcode *err)
+{
+ struct connectdata *conn = data->conn;
+ struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_client_session *const session = backend->session;
+ curl_socket_t sockfd = conn->sock[sockindex];
+ size_t n = 0;
+ ssize_t tls_bytes_read = 0;
+ size_t tls_bytes_processed = 0;
+ size_t plain_bytes_copied = 0;
+ rustls_result rresult = 0;
+ char errorbuf[255];
+
+ tls_bytes_read = sread(sockfd, backend->tlsbuf, TLSBUF_SIZE);
+ if(tls_bytes_read == 0) {
+ failf(data, "connection closed without TLS close_notify alert");
+ *err = CURLE_READ_ERROR;
+ return -1;
+ }
+ else if(tls_bytes_read < 0) {
+ if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
+ infof(data, "sread: EAGAIN or EWOULDBLOCK\n");
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+ failf(data, "reading from socket: %s", strerror(SOCKERRNO));
+ *err = CURLE_READ_ERROR;
+ return -1;
+ }
+
+ /*
+ * Now pull those bytes from the buffer into ClientSession.
+ */
+ DEBUGASSERT(tls_bytes_read > 0);
+ while(tls_bytes_processed < (size_t)tls_bytes_read) {
+ rresult = rustls_client_session_read_tls(session,
+ backend->tlsbuf + tls_bytes_processed,
+ tls_bytes_read - tls_bytes_processed,
+ &n);
+ if(rresult != RUSTLS_RESULT_OK) {
+ failf(data, "error in rustls_client_session_read_tls");
+ *err = CURLE_READ_ERROR;
+ return -1;
+ }
+ else if(n == 0) {
+ infof(data, "EOF from rustls_client_session_read_tls\n");
+ break;
+ }
+
+ rresult = rustls_client_session_process_new_packets(session);
+ if(rresult != RUSTLS_RESULT_OK) {
+ rustls_error(rresult, errorbuf, sizeof(errorbuf), &n);
+ failf(data, "%.*s", n, errorbuf);
+ *err = map_error(rresult);
+ return -1;
+ }
+
+ tls_bytes_processed += n;
+ backend->data_pending = TRUE;
+ }
+
+ while(plain_bytes_copied < plainlen) {
+ rresult = rustls_client_session_read(session,
+ (uint8_t *)plainbuf + plain_bytes_copied,
+ plainlen - plain_bytes_copied,
+ &n);
+ if(rresult == RUSTLS_RESULT_ALERT_CLOSE_NOTIFY) {
+ *err = CURLE_OK;
+ return 0;
+ }
+ else if(rresult != RUSTLS_RESULT_OK) {
+ failf(data, "error in rustls_client_session_read");
+ *err = CURLE_READ_ERROR;
+ return -1;
+ }
+ else if(n == 0) {
+ /* rustls returns 0 from client_session_read to mean "all currently
+ available data has been read." If we bring in more ciphertext with
+ read_tls, more plaintext will become available. So don't tell curl
+ this is an EOF. Instead, say "come back later." */
+ infof(data, "EOF from rustls_client_session_read\n");
+ backend->data_pending = FALSE;
+ break;
+ }
+ else {
+ plain_bytes_copied += n;
+ }
+ }
+
+ /* If we wrote out 0 plaintext bytes, it might just mean we haven't yet
+ read a full TLS record. Return CURLE_AGAIN so curl doesn't treat this
+ as EOF. */
+ if(plain_bytes_copied == 0) {
+ *err = CURLE_AGAIN;
+ return -1;
+ }
+
+ return plain_bytes_copied;
+}
+
+/*
+ * On each call:
+ * - Copy `plainlen` bytes into rustls' plaintext input buffer (if > 0).
+ * - Fully drain rustls' plaintext output buffer into the socket until
+ * we get either an error or EAGAIN/EWOULDBLOCK.
+ *
+ * It's okay to call this function with plainbuf == NULL and plainlen == 0.
+ * In that case, it won't read anything into rustls' plaintext input buffer.
+ * It will only drain rustls' plaintext output buffer into the socket.
+ */
+static ssize_t
+cr_send(struct Curl_easy *data, int sockindex,
+ const void *plainbuf, size_t plainlen, CURLcode *err)
+{
+ struct connectdata *conn = data->conn;
+ struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_client_session *const session = backend->session;
+ curl_socket_t sockfd = conn->sock[sockindex];
+ ssize_t n = 0;
+ size_t plainwritten = 0;
+ size_t tlslen = 0;
+ size_t tlswritten = 0;
+ rustls_result rresult;
+
+ if(plainlen > 0) {
+ rresult = rustls_client_session_write(session,
+ plainbuf, plainlen, &plainwritten);
+ if(rresult != RUSTLS_RESULT_OK) {
+ failf(data, "error in rustls_client_session_write");
+ *err = CURLE_WRITE_ERROR;
+ return -1;
+ }
+ else if(plainwritten == 0) {
+ failf(data, "EOF in rustls_client_session_write");
+ *err = CURLE_WRITE_ERROR;
+ return -1;
+ }
+ }
+
+ while(rustls_client_session_wants_write(session)) {
+ rresult = rustls_client_session_write_tls(
+ session, backend->tlsbuf, TLSBUF_SIZE, &tlslen);
+ if(rresult != RUSTLS_RESULT_OK) {
+ failf(data, "error in rustls_client_session_write_tls");
+ *err = CURLE_WRITE_ERROR;
+ return -1;
+ }
+ else if(tlslen == 0) {
+ failf(data, "EOF in rustls_client_session_write_tls");
+ *err = CURLE_WRITE_ERROR;
+ return -1;
+ }
+
+ tlswritten = 0;
+
+ while(tlswritten < tlslen) {
+ n = swrite(sockfd, backend->tlsbuf + tlswritten, tlslen - tlswritten);
+ if(n < 0) {
+ if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) {
+ /* Since recv is called from poll, there should be room to
+ write at least some bytes before hitting EAGAIN. */
+ infof(data, "swrite: EAGAIN after %ld bytes\n", tlswritten);
+ DEBUGASSERT(tlswritten > 0);
+ break;
+ }
+ failf(data, "error in swrite");
+ *err = CURLE_WRITE_ERROR;
+ return -1;
+ }
+ if(n == 0) {
+ failf(data, "EOF in swrite");
+ *err = CURLE_WRITE_ERROR;
+ return -1;
+ }
+ tlswritten += n;
+ }
+
+ DEBUGASSERT(tlswritten <= tlslen);
+ }
+
+ return plainwritten;
+}
+
+/* A server certificate verify callback for rustls that always returns
+ RUSTLS_RESULT_OK, or in other words disable certificate verification. */
+static enum rustls_result
+cr_verify_none(void *userdata UNUSED_PARAM,
+ const rustls_verify_server_cert_params *params UNUSED_PARAM)
+{
+ return RUSTLS_RESULT_OK;
+}
+
+static bool
+cr_hostname_is_ip(const char *hostname)
+{
+ struct in_addr in;
+#ifdef ENABLE_IPV6
+ struct in6_addr in6;
+ if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0) {
+ return true;
+ }
+#endif /* ENABLE_IPV6 */
+ if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
+ return true;
+ }
+ return false;
+}
+
+static CURLcode
+cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
+ struct ssl_backend_data *const backend)
+{
+ struct rustls_client_session *session = backend->session;
+ struct rustls_client_config_builder *config_builder = NULL;
+ const char *const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+ const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+ const char *hostname = conn->host.name;
+ char errorbuf[256];
+ size_t errorlen;
+ int result;
+
+ backend->tlsbuf = calloc(TLSBUF_SIZE, 1);
+ if(backend->tlsbuf == NULL) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ config_builder = rustls_client_config_builder_new();
+ if(!verifypeer) {
+ rustls_client_config_builder_dangerous_set_certificate_verifier(
+ config_builder, cr_verify_none, NULL);
+ /* rustls doesn't support IP addresses (as of 0.19.0), and will reject
+ * sessions created with an IP address, even when certificate verification
+ * is turned off. Set a placeholder hostname and disable SNI. */
+ if(cr_hostname_is_ip(hostname)) {
+ rustls_client_config_builder_set_enable_sni(config_builder, false);
+ hostname = "example.invalid";
+ }
+ }
+ else if(ssl_cafile) {
+ result = rustls_client_config_builder_load_roots_from_file(
+ config_builder, ssl_cafile);
+ if(result != RUSTLS_RESULT_OK) {
+ failf(data, "failed to load trusted certificates");
+ rustls_client_config_free(
+ rustls_client_config_builder_build(config_builder));
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ }
+ else {
+ result = rustls_client_config_builder_load_native_roots(config_builder);
+ if(result != RUSTLS_RESULT_OK) {
+ failf(data, "failed to load trusted certificates");
+ rustls_client_config_free(
+ rustls_client_config_builder_build(config_builder));
+ return CURLE_SSL_CACERT_BADFILE;
+ }
+ }
+
+ backend->config = rustls_client_config_builder_build(config_builder);
+ DEBUGASSERT(session == NULL);
+ result = rustls_client_session_new(
+ backend->config, hostname, &session);
+ if(result != RUSTLS_RESULT_OK) {
+ rustls_error(result, errorbuf, sizeof(errorbuf), &errorlen);
+ failf(data, "failed to create client session: %.*s", errorlen, errorbuf);
+ return CURLE_COULDNT_CONNECT;
+ }
+ backend->session = session;
+ return CURLE_OK;
+}
+
+static CURLcode
+cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
+ int sockindex, bool *done)
+{
+ struct ssl_connect_data *const connssl = &conn->ssl[sockindex];
+ curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_client_session *session = NULL;
+ CURLcode tmperr = CURLE_OK;
+ int result;
+ int what;
+ bool wants_read;
+ bool wants_write;
+ curl_socket_t writefd;
+ curl_socket_t readfd;
+
+ if(ssl_connection_none == connssl->state) {
+ result = cr_init_backend(data, conn, connssl->backend);
+ if(result != CURLE_OK) {
+ return result;
+ }
+ connssl->state = ssl_connection_negotiating;
+ }
+
+ session = backend->session;
+
+ /* Read/write data until the handshake is done or the socket would block. */
+ for(;;) {
+ /*
+ * Connection has been established according to rustls. Set send/recv
+ * handlers, and update the state machine.
+ * This check has to come last because is_handshaking starts out false,
+ * then becomes true when we first write data, then becomes false again
+ * once the handshake is done.
+ */
+ if(!rustls_client_session_is_handshaking(session)) {
+ infof(data, "Done handshaking\n");
+ /* Done with the handshake. Set up callbacks to send/receive data. */
+ connssl->state = ssl_connection_complete;
+ conn->recv[sockindex] = cr_recv;
+ conn->send[sockindex] = cr_send;
+ *done = TRUE;
+ return CURLE_OK;
+ }
+
+ wants_read = rustls_client_session_wants_read(session);
+ wants_write = rustls_client_session_wants_write(session);
+ DEBUGASSERT(wants_read || wants_write);
+ writefd = wants_write?sockfd:CURL_SOCKET_BAD;
+ readfd = wants_read?sockfd:CURL_SOCKET_BAD;
+
+ what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, 0);
+ if(what < 0) {
+ /* fatal error */
+ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ if(0 == what) {
+ infof(data, "Curl_socket_check: %s would block\n",
+ wants_read&&wants_write ?
+ "writing and reading" :
+ wants_write ?
+ "writing" :
+ "reading");
+ *done = FALSE;
+ return CURLE_OK;
+ }
+ /* socket is readable or writable */
+
+ if(wants_write) {
+ infof(data, "ClientSession wants us to write_tls.\n");
+ cr_send(data, sockindex, NULL, 0, &tmperr);
+ if(tmperr == CURLE_AGAIN) {
+ infof(data, "writing would block\n");
+ /* fall through */
+ }
+ else if(tmperr != CURLE_OK) {
+ return tmperr;
+ }
+ }
+
+ if(wants_read) {
+ infof(data, "ClientSession wants us to read_tls.\n");
+
+ cr_recv(data, sockindex, NULL, 0, &tmperr);
+ if(tmperr == CURLE_AGAIN) {
+ infof(data, "reading would block\n");
+ /* fall through */
+ }
+ else if(tmperr != CURLE_OK) {
+ if(tmperr == CURLE_READ_ERROR) {
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ else {
+ return tmperr;
+ }
+ }
+ }
+ }
+
+ /* We should never fall through the loop. We should return either because
+ the handshake is done or because we can't read/write without blocking. */
+ DEBUGASSERT(false);
+}
+
+/* returns a bitmap of flags for this connection's first socket indicating
+ whether we want to read or write */
+static int
+cr_getsock(struct connectdata *conn, curl_socket_t *socks)
+{
+ struct ssl_connect_data *const connssl = &conn->ssl[FIRSTSOCKET];
+ curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+ struct ssl_backend_data *const backend = connssl->backend;
+ struct rustls_client_session *session = backend->session;
+
+ if(rustls_client_session_wants_write(session)) {
+ socks[0] = sockfd;
+ return GETSOCK_WRITESOCK(0);
+ }
+ if(rustls_client_session_wants_read(session)) {
+ socks[0] = sockfd;
+ return GETSOCK_READSOCK(0);
+ }
+
+ return GETSOCK_BLANK;
+}
+
+static void *
+cr_get_internals(struct ssl_connect_data *connssl,
+ CURLINFO info UNUSED_PARAM)
+{
+ struct ssl_backend_data *backend = connssl->backend;
+ return &backend->session;
+}
+
+static void
+cr_close(struct Curl_easy *data, struct connectdata *conn,
+ int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_backend_data *backend = connssl->backend;
+ CURLcode tmperr = CURLE_OK;
+ ssize_t n = 0;
+
+ if(backend->session) {
+ rustls_client_session_send_close_notify(backend->session);
+ n = cr_send(data, sockindex, NULL, 0, &tmperr);
+ if(n < 0) {
+ failf(data, "error sending close notify: %d", tmperr);
+ }
+
+ rustls_client_session_free(backend->session);
+ backend->session = NULL;
+ }
+ if(backend->config) {
+ rustls_client_config_free(backend->config);
+ backend->config = NULL;
+ }
+ free(backend->tlsbuf);
+}
+
+const struct Curl_ssl Curl_ssl_rustls = {
+ { CURLSSLBACKEND_RUSTLS, "rustls" },
+ SSLSUPP_TLS13_CIPHERSUITES, /* supports */
+ sizeof(struct ssl_backend_data),
+
+ Curl_none_init, /* init */
+ Curl_none_cleanup, /* cleanup */
+ rustls_version, /* version */
+ Curl_none_check_cxn, /* check_cxn */
+ Curl_none_shutdown, /* shutdown */
+ cr_data_pending, /* data_pending */
+ Curl_none_random, /* random */
+ Curl_none_cert_status_request, /* cert_status_request */
+ cr_connect, /* connect */
+ cr_connect_nonblocking, /* connect_nonblocking */
+ cr_getsock, /* cr_getsock */
+ cr_get_internals, /* get_internals */
+ cr_close, /* close_one */
+ Curl_none_close_all, /* close_all */
+ Curl_none_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 */
+ NULL /* sha256sum */
+};
+
+#endif /* USE_RUSTLS */
diff --git a/contrib/libs/curl/lib/vtls/rustls.h b/contrib/libs/curl/lib/vtls/rustls.h
new file mode 100644
index 0000000000..056211dd8b
--- /dev/null
+++ b/contrib/libs/curl/lib/vtls/rustls.h
@@ -0,0 +1,33 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020 - 2021, Jacob Hoffman-Andrews,
+ * <github@hoffman-andrews.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef HEADER_CURL_RUSTLS_H
+#define HEADER_CURL_RUSTLS_H
+
+#include "curl_setup.h"
+
+#ifdef USE_RUSTLS
+
+extern const struct Curl_ssl Curl_ssl_rustls;
+
+#endif /* USE_RUSTLS */
+#endif /* HEADER_CURL_RUSTLS_H */
diff --git a/contrib/libs/curl/lib/vtls/schannel.c b/contrib/libs/curl/lib/vtls/schannel.c
index aa80f3b576..51cf940b4d 100644
--- a/contrib/libs/curl/lib/vtls/schannel.c
+++ b/contrib/libs/curl/lib/vtls/schannel.c
@@ -496,6 +496,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
if(SSL_SET_OPTION(primary.sessionid)) {
Curl_ssl_sessionid_lock(data);
if(!Curl_ssl_getsessionid(data, conn,
+ SSL_IS_PROXY() ? TRUE : FALSE,
(void **)&old_cred, NULL, sockindex)) {
BACKEND->cred = old_cred;
DEBUGF(infof(data, "schannel: re-using existing credential handle\n"));
@@ -522,14 +523,14 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
#endif
schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
- if(data->set.ssl.no_revoke) {
+ if(SSL_SET_OPTION(no_revoke)) {
schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
DEBUGF(infof(data, "schannel: disabled server certificate revocation "
"checks\n"));
}
- else if(data->set.ssl.revoke_best_effort) {
+ else if(SSL_SET_OPTION(revoke_best_effort)) {
schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN;
@@ -861,7 +862,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
list_start_index = cur;
#ifdef USE_NGHTTP2
- if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+ if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
memcpy(&alpn_buffer[cur], NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN);
cur += NGHTTP2_PROTO_ALPN_LEN;
infof(data, "schannel: ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
@@ -1252,7 +1253,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
pubkey_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(pubkey_ptr) {
result = pkp_pin_peer_pubkey(data, conn, sockindex, pubkey_ptr);
if(result) {
@@ -1337,8 +1338,9 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
SECURITY_STATUS sspi_status = SEC_E_OK;
CERT_CONTEXT *ccert_context = NULL;
+ bool isproxy = SSL_IS_PROXY();
#ifdef DEBUGBUILD
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+ const char * const hostname = isproxy ? conn->http_proxy.host.name :
conn->host.name;
#endif
#ifdef HAS_ALPN
@@ -1414,8 +1416,8 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
struct Curl_schannel_cred *old_cred = NULL;
Curl_ssl_sessionid_lock(data);
- incache = !(Curl_ssl_getsessionid(data, conn, (void **)&old_cred, NULL,
- sockindex));
+ incache = !(Curl_ssl_getsessionid(data, conn, isproxy, (void **)&old_cred,
+ NULL, sockindex));
if(incache) {
if(old_cred != BACKEND->cred) {
DEBUGF(infof(data,
@@ -1426,7 +1428,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
}
}
if(!incache) {
- result = Curl_ssl_addsessionid(data, conn, (void *)BACKEND->cred,
+ result = Curl_ssl_addsessionid(data, conn, isproxy, BACKEND->cred,
sizeof(struct Curl_schannel_cred),
sockindex);
if(result) {
@@ -2418,6 +2420,7 @@ const struct Curl_ssl Curl_ssl_schannel = {
Curl_none_cert_status_request, /* cert_status_request */
schannel_connect, /* connect */
schannel_connect_nonblocking, /* connect_nonblocking */
+ Curl_ssl_getsock, /* getsock */
schannel_get_internals, /* get_internals */
schannel_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/contrib/libs/curl/lib/vtls/schannel_verify.c b/contrib/libs/curl/lib/vtls/schannel_verify.c
index 2ef39cc0f4..e0fdbd5b63 100644
--- a/contrib/libs/curl/lib/vtls/schannel_verify.c
+++ b/contrib/libs/curl/lib/vtls/schannel_verify.c
@@ -624,7 +624,7 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
NULL,
pCertContextServer->hCertStore,
&ChainPara,
- (data->set.ssl.no_revoke ? 0 :
+ (SSL_SET_OPTION(no_revoke) ? 0 :
CERT_CHAIN_REVOCATION_CHECK_CHAIN),
NULL,
&pChainContext)) {
diff --git a/contrib/libs/curl/lib/vtls/sectransp.c b/contrib/libs/curl/lib/vtls/sectransp.c
index 9a8f7de8d5..9d637da2ec 100644
--- a/contrib/libs/curl/lib/vtls/sectransp.c
+++ b/contrib/libs/curl/lib/vtls/sectransp.c
@@ -1400,10 +1400,12 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
#ifndef CURL_DISABLE_PROXY
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+ bool isproxy = SSL_IS_PROXY();
+ const char * const hostname = isproxy ? conn->http_proxy.host.name :
conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
#else
+ const isproxy = FALSE;
const char * const hostname = conn->host.name;
const long int port = conn->remote_port;
#endif
@@ -1611,9 +1613,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
&kCFTypeArrayCallBacks);
#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)
+ && (!isproxy || !conn->bits.tunnel_proxy)
#endif
) {
CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID));
@@ -1941,7 +1943,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
specifically doesn't want us doing that: */
if(SSLSetSessionOption != NULL) {
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
- !data->set.ssl.enable_beast);
+ !SSL_SET_OPTION(enable_beast));
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
data->set.ssl.falsestart); /* false start support */
}
@@ -1953,7 +1955,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
size_t ssl_sessionid_len;
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, (void **)&ssl_sessionid,
+ if(!Curl_ssl_getsessionid(data, conn, isproxy, (void **)&ssl_sessionid,
&ssl_sessionid_len, sockindex)) {
/* we got a session id, use it! */
err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
@@ -1981,7 +1983,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
return CURLE_SSL_CONNECT_ERROR;
}
- result = Curl_ssl_addsessionid(data, conn, ssl_sessionid,
+ result = Curl_ssl_addsessionid(data, conn, isproxy, ssl_sessionid,
ssl_sessionid_len, sockindex);
Curl_ssl_sessionid_unlock(data);
if(result) {
@@ -2621,9 +2623,10 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
connssl->connecting_state = ssl_connect_3;
#ifdef SECTRANSP_PINNEDPUBKEY
- if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
- CURLcode result = pkp_pin_peer_pubkey(data, backend->ssl_ctx,
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
+ if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
+ CURLcode result =
+ pkp_pin_peer_pubkey(data, backend->ssl_ctx,
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
if(result) {
failf(data, "SSL: public key does not match pinned public key!");
return result;
@@ -3301,6 +3304,7 @@ const struct Curl_ssl Curl_ssl_sectransp = {
Curl_none_cert_status_request, /* cert_status_request */
sectransp_connect, /* connect */
sectransp_connect_nonblocking, /* connect_nonblocking */
+ Curl_ssl_getsock, /* getsock */
sectransp_get_internals, /* get_internals */
sectransp_close, /* close_one */
Curl_none_close_all, /* close_all */
diff --git a/contrib/libs/curl/lib/vtls/vtls.c b/contrib/libs/curl/lib/vtls/vtls.c
index b8ab7494fd..2e07df0a04 100644
--- a/contrib/libs/curl/lib/vtls/vtls.c
+++ b/contrib/libs/curl/lib/vtls/vtls.c
@@ -367,6 +367,7 @@ void Curl_ssl_sessionid_unlock(struct Curl_easy *data)
*/
bool Curl_ssl_getsessionid(struct Curl_easy *data,
struct connectdata *conn,
+ const bool isProxy,
void **ssl_sessionid,
size_t *idsize, /* set 0 if unknown */
int sockindex)
@@ -377,7 +378,6 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data,
bool no_match = TRUE;
#ifndef CURL_DISABLE_PROXY
- const bool isProxy = CONNECT_PROXY_SSL();
struct ssl_primary_config * const ssl_config = isProxy ?
&conn->proxy_ssl_config :
&conn->ssl_config;
@@ -389,10 +389,15 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data,
struct ssl_primary_config * const ssl_config = &conn->ssl_config;
const char * const name = conn->host.name;
int port = conn->remote_port;
- (void)sockindex;
#endif
+ (void)sockindex;
*ssl_sessionid = NULL;
+#ifdef CURL_DISABLE_PROXY
+ if(isProxy)
+ return TRUE;
+#endif
+
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
if(!SSL_SET_OPTION(primary.sessionid))
@@ -480,6 +485,7 @@ void Curl_ssl_delsessionid(struct Curl_easy *data, void *ssl_sessionid)
*/
CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
struct connectdata *conn,
+ bool isProxy,
void *ssl_sessionid,
size_t idsize,
int sockindex)
@@ -492,19 +498,16 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
int conn_to_port;
long *general_age;
#ifndef CURL_DISABLE_PROXY
- const bool isProxy = CONNECT_PROXY_SSL();
struct ssl_primary_config * const ssl_config = isProxy ?
&conn->proxy_ssl_config :
&conn->ssl_config;
const char *hostname = isProxy ? conn->http_proxy.host.name :
conn->host.name;
#else
- /* proxy support disabled */
- const bool isProxy = FALSE;
struct ssl_primary_config * const ssl_config = &conn->ssl_config;
const char *hostname = conn->host.name;
- (void)sockindex;
#endif
+ (void)sockindex;
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
clone_host = strdup(hostname);
@@ -593,9 +596,6 @@ void Curl_ssl_close_all(struct Curl_easy *data)
Curl_ssl->close_all(data);
}
-#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
- defined(USE_SECTRANSP) || defined(USE_NSS) || \
- defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_BEARSSL)
int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks)
{
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
@@ -613,16 +613,6 @@ int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks)
return GETSOCK_BLANK;
}
-#else
-int Curl_ssl_getsock(struct connectdata *conn,
- curl_socket_t *socks)
-{
- (void)conn;
- (void)socks;
- return GETSOCK_BLANK;
-}
-/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_SECTRANSP || USE_NSS */
-#endif
void Curl_ssl_close(struct Curl_easy *data, struct connectdata *conn,
int sockindex)
@@ -1170,6 +1160,13 @@ static CURLcode multissl_connect_nonblocking(struct Curl_easy *data,
return Curl_ssl->connect_nonblocking(data, conn, sockindex, done);
}
+static int multissl_getsock(struct connectdata *conn, curl_socket_t *socks)
+{
+ if(multissl_setup(NULL))
+ return 0;
+ return Curl_ssl->getsock(conn, socks);
+}
+
static void *multissl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info)
{
@@ -1201,6 +1198,7 @@ static const struct Curl_ssl Curl_ssl_multi = {
Curl_none_cert_status_request, /* cert_status_request */
multissl_connect, /* connect */
multissl_connect_nonblocking, /* connect_nonblocking */
+ multissl_getsock, /* getsock */
multissl_get_internals, /* get_internals */
multissl_close, /* close_one */
Curl_none_close_all, /* close_all */
@@ -1227,6 +1225,8 @@ const struct Curl_ssl *Curl_ssl =
&Curl_ssl_mbedtls;
#elif defined(USE_NSS)
&Curl_ssl_nss;
+#elif defined(USE_RUSTLS)
+ &Curl_ssl_rustls;
#elif defined(USE_OPENSSL)
&Curl_ssl_openssl;
#elif defined(USE_SCHANNEL)
@@ -1270,6 +1270,9 @@ static const struct Curl_ssl *available_backends[] = {
#if defined(USE_BEARSSL)
&Curl_ssl_bearssl,
#endif
+#if defined(USE_RUSTLS)
+ &Curl_ssl_rustls,
+#endif
NULL
};
diff --git a/contrib/libs/curl/lib/vtls/vtls.h b/contrib/libs/curl/lib/vtls/vtls.h
index 9666682ec2..2b43e7744b 100644
--- a/contrib/libs/curl/lib/vtls/vtls.h
+++ b/contrib/libs/curl/lib/vtls/vtls.h
@@ -62,6 +62,14 @@ struct Curl_ssl {
CURLcode (*connect_nonblocking)(struct Curl_easy *data,
struct connectdata *conn, int sockindex,
bool *done);
+
+ /* If the SSL backend wants to read or write on this connection during a
+ handshake, set socks[0] to the connection's FIRSTSOCKET, and return
+ a bitmap indicating read or write with GETSOCK_WRITESOCK(0) or
+ GETSOCK_READSOCK(0). Otherwise return GETSOCK_BLANK.
+ Mandatory. */
+ int (*getsock)(struct connectdata *conn, curl_socket_t *socks);
+
void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info);
void (*close_one)(struct Curl_easy *data, struct connectdata *conn,
int sockindex);
@@ -108,6 +116,7 @@ bool Curl_ssl_tls13_ciphersuites(void);
#include "mbedtls.h" /* mbedTLS versions */
#include "mesalink.h" /* MesaLink versions */
#include "bearssl.h" /* BearSSL versions */
+#include "rustls.h" /* rustls versions */
#ifndef MAX_PINNED_PUBKEY_SIZE
#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
@@ -141,7 +150,7 @@ bool Curl_ssl_tls13_ciphersuites(void);
(SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname)
#define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \
? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \
- : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG])
+ : data->set.str[STRING_SSL_PINNEDPUBLICKEY])
#else
#define SSL_IS_PROXY() FALSE
#define SSL_SET_OPTION(var) data->set.ssl.var
@@ -150,7 +159,7 @@ bool Curl_ssl_tls13_ciphersuites(void);
#define SSL_HOST_NAME() conn->host.name
#define SSL_HOST_DISPNAME() conn->host.dispname
#define SSL_PINNED_PUB_KEY() \
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY]
#endif
bool Curl_ssl_config_matches(struct ssl_primary_config *data,
@@ -158,6 +167,10 @@ bool Curl_ssl_config_matches(struct ssl_primary_config *data,
bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
struct ssl_primary_config *dest);
void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc);
+/* An implementation of the getsock field of Curl_ssl that relies
+ on the ssl_connect_state enum. Asks for read or write depending
+ on whether conn->state is ssl_connect_2_reading or
+ ssl_connect_2_writing. */
int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks);
int Curl_ssl_backend(void);
@@ -222,6 +235,7 @@ void Curl_ssl_sessionid_unlock(struct Curl_easy *data);
*/
bool Curl_ssl_getsessionid(struct Curl_easy *data,
struct connectdata *conn,
+ const bool isproxy,
void **ssl_sessionid,
size_t *idsize, /* set 0 if unknown */
int sockindex);
@@ -232,6 +246,7 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data,
*/
CURLcode Curl_ssl_addsessionid(struct Curl_easy *data,
struct connectdata *conn,
+ const bool isProxy,
void *ssl_sessionid,
size_t idsize,
int sockindex);
diff --git a/contrib/libs/curl/lib/vtls/wolfssl.c b/contrib/libs/curl/lib/vtls/wolfssl.c
index 334b88fbae..f7534ef918 100644
--- a/contrib/libs/curl/lib/vtls/wolfssl.c
+++ b/contrib/libs/curl/lib/vtls/wolfssl.c
@@ -475,7 +475,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
protocols in descending order of preference, eg: "h2,http/1.1" */
#ifdef USE_NGHTTP2
- if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+ if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ",");
infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
}
@@ -516,7 +516,9 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
void *ssl_sessionid = NULL;
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)) {
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
@@ -557,12 +559,12 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
conn->http_proxy.host.dispname : conn->host.dispname;
const char * const pinnedpubkey = SSL_IS_PROXY() ?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
#else
const char * const hostname = conn->host.name;
const char * const dispname = conn->host.dispname;
const char * const pinnedpubkey =
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
#endif
conn->recv[sockindex] = wolfssl_recv;
@@ -724,7 +726,7 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
!memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
conn->negnpn = CURL_HTTP_VERSION_1_1;
#ifdef USE_NGHTTP2
- else if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+ else if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN &&
!memcmp(protocol, NGHTTP2_PROTO_VERSION_ID,
NGHTTP2_PROTO_VERSION_ID_LEN))
@@ -770,32 +772,33 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn,
if(SSL_SET_OPTION(primary.sessionid)) {
bool incache;
- SSL_SESSION *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
-
- our_ssl_sessionid = SSL_get_session(backend->handle);
-
- Curl_ssl_sessionid_lock(data);
- incache = !(Curl_ssl_getsessionid(data, 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(data, old_ssl_sessionid);
- incache = FALSE;
+ SSL_SESSION *our_ssl_sessionid = SSL_get_session(backend->handle);
+ bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
+
+ if(our_ssl_sessionid) {
+ Curl_ssl_sessionid_lock(data);
+ incache = !(Curl_ssl_getsessionid(data, conn, isproxy,
+ &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(data, old_ssl_sessionid);
+ incache = FALSE;
+ }
}
- }
- if(!incache) {
- result = Curl_ssl_addsessionid(data, conn, our_ssl_sessionid,
- 0 /* unknown size */, sockindex);
- if(result) {
- Curl_ssl_sessionid_unlock(data);
- failf(data, "failed to store ssl session");
- return result;
+ if(!incache) {
+ result = Curl_ssl_addsessionid(data, conn, isproxy, our_ssl_sessionid,
+ 0, sockindex);
+ if(result) {
+ Curl_ssl_sessionid_unlock(data);
+ failf(data, "failed to store ssl session");
+ return result;
+ }
}
+ Curl_ssl_sessionid_unlock(data);
}
- Curl_ssl_sessionid_unlock(data);
}
connssl->connecting_state = ssl_connect_done;
@@ -1152,6 +1155,7 @@ const struct Curl_ssl Curl_ssl_wolfssl = {
Curl_none_cert_status_request, /* cert_status_request */
wolfssl_connect, /* connect */
wolfssl_connect_nonblocking, /* connect_nonblocking */
+ Curl_ssl_getsock, /* getsock */
wolfssl_get_internals, /* get_internals */
wolfssl_close, /* close_one */
Curl_none_close_all, /* close_all */