mirror of
https://github.com/curl/curl.git
synced 2026-06-10 05:14:15 +03:00
mbedTLS: clean-up insecure/deprecated code, and other fixes
This commit is contained in:
parent
c27a2db54f
commit
742a66f88d
6 changed files with 256 additions and 425 deletions
|
|
@ -61,6 +61,13 @@ does this cleanup automatically and there is no leak (added in libcurl 8.8.0).
|
|||
Please review the OpenSSL documentation for a full list of circumstances:
|
||||
https://docs.openssl.org/3.0/man3/OPENSSL_init_crypto/#notes
|
||||
|
||||
## mbedTLS
|
||||
|
||||
mbedTLS can be used safely in a multi-threaded environment provided that mbedTLS is
|
||||
compiled with MBEDTLS_THREADING_C enabled.
|
||||
|
||||
https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading
|
||||
|
||||
# Signals
|
||||
|
||||
Signals are used for timing out name resolves (during DNS lookup) - when built
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@
|
|||
***************************************************************************/
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#if defined(USE_MBEDTLS) || defined(USE_RUSTLS)
|
||||
#if !defined(CURL_DISABLE_CERTINFO) && \
|
||||
(defined(USE_MBEDTLS) || defined(USE_RUSTLS))
|
||||
#include "cipher_suite.h"
|
||||
#include "../curl_printf.h"
|
||||
#include <string.h>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@
|
|||
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#if defined(USE_MBEDTLS) || defined(USE_RUSTLS)
|
||||
#if !defined(CURL_DISABLE_CERTINFO) && \
|
||||
(defined(USE_MBEDTLS) || defined(USE_RUSTLS))
|
||||
#include <stdint.h>
|
||||
|
||||
/* Lookup IANA id for cipher suite string, returns 0 if not recognized */
|
||||
|
|
|
|||
|
|
@ -33,15 +33,8 @@
|
|||
|
||||
#ifdef USE_MBEDTLS
|
||||
|
||||
/* Define this to enable lots of debugging for mbedTLS */
|
||||
/* #define MBEDTLS_DEBUG */
|
||||
|
||||
#include <mbedtls/version.h>
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x02040000
|
||||
#include <mbedtls/net_sockets.h>
|
||||
#else
|
||||
#include <mbedtls/net.h>
|
||||
#endif
|
||||
#include <mbedtls/ssl.h>
|
||||
#include <mbedtls/x509.h>
|
||||
|
||||
|
|
@ -50,11 +43,13 @@
|
|||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
|
||||
#if MBEDTLS_VERSION_MAJOR >= 2
|
||||
# ifdef MBEDTLS_DEBUG
|
||||
# include <mbedtls/debug.h>
|
||||
# endif
|
||||
#endif /* MBEDTLS_VERSION_MAJOR >= 2 */
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
#include <psa/crypto.h>
|
||||
#endif
|
||||
|
||||
#ifdef MBEDTLS_DEBUG_C
|
||||
# include <mbedtls/debug.h>
|
||||
#endif
|
||||
|
||||
#include "cipher_suite.h"
|
||||
#include "../urldata.h"
|
||||
|
|
@ -69,7 +64,6 @@
|
|||
#include "../connect.h" /* for the connect timeout */
|
||||
#include "../select.h"
|
||||
#include "../multiif.h"
|
||||
#include "mbedtls_threadlock.h"
|
||||
#include "../strdup.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
|
|
@ -103,10 +97,20 @@ struct mbed_ssl_backend_data {
|
|||
BIT(send_blocked);
|
||||
};
|
||||
|
||||
/* apply threading? */
|
||||
#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || defined(_WIN32)
|
||||
#define HAS_THREADING_SUPPORT
|
||||
/** A context for random number generation (RNG).
|
||||
*/
|
||||
struct rng_context_t {
|
||||
mbedtls_entropy_context entropy;
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
mbedtls_ctr_drbg_context drbg;
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
mbedtls_hmac_drbg_context drbg;
|
||||
#else
|
||||
#error "No DRBG available"
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct rng_context_t rng;
|
||||
|
||||
#ifndef MBEDTLS_ERROR_C
|
||||
#define mbedtls_strerror(a,b,c) b[0] = 0
|
||||
|
|
@ -125,47 +129,7 @@ struct mbed_ssl_backend_data {
|
|||
#define HAS_SESSION_TICKETS
|
||||
#endif
|
||||
|
||||
#ifdef HAS_THREADING_SUPPORT
|
||||
static mbedtls_entropy_context ts_entropy;
|
||||
|
||||
static int entropy_init_initialized = 0;
|
||||
|
||||
static void entropy_init_mutex(mbedtls_entropy_context *ctx)
|
||||
{
|
||||
/* lock 0 = entropy_init_mutex() */
|
||||
Curl_mbedtlsthreadlock_lock_function(0);
|
||||
if(entropy_init_initialized == 0) {
|
||||
mbedtls_entropy_init(ctx);
|
||||
entropy_init_initialized = 1;
|
||||
}
|
||||
Curl_mbedtlsthreadlock_unlock_function(0);
|
||||
}
|
||||
|
||||
static void entropy_cleanup_mutex(mbedtls_entropy_context *ctx)
|
||||
{
|
||||
/* lock 0 = use same lock as init */
|
||||
Curl_mbedtlsthreadlock_lock_function(0);
|
||||
if(entropy_init_initialized == 1) {
|
||||
mbedtls_entropy_free(ctx);
|
||||
entropy_init_initialized = 0;
|
||||
}
|
||||
Curl_mbedtlsthreadlock_unlock_function(0);
|
||||
}
|
||||
|
||||
static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
|
||||
{
|
||||
int ret;
|
||||
/* lock 1 = entropy_func_mutex() */
|
||||
Curl_mbedtlsthreadlock_lock_function(1);
|
||||
ret = mbedtls_entropy_func(data, output, len);
|
||||
Curl_mbedtlsthreadlock_unlock_function(1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAS_THREADING_SUPPORT */
|
||||
|
||||
#ifdef MBEDTLS_DEBUG
|
||||
#ifdef MBEDTLS_DEBUG_C
|
||||
static void mbed_debug(void *context, int level, const char *f_name,
|
||||
int line_nb, const char *line)
|
||||
{
|
||||
|
|
@ -215,6 +179,7 @@ static int mbedtls_bio_cf_read(void *bio, unsigned char *buf, size_t blen)
|
|||
DEBUGASSERT(data);
|
||||
if(!data)
|
||||
return 0;
|
||||
|
||||
/* OpenSSL catches this case, so should we. */
|
||||
if(!buf)
|
||||
return 0;
|
||||
|
|
@ -227,22 +192,6 @@ static int mbedtls_bio_cf_read(void *bio, unsigned char *buf, size_t blen)
|
|||
return result ? -1 : (int)nread;
|
||||
}
|
||||
|
||||
/*
|
||||
* profile
|
||||
*/
|
||||
static const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
|
||||
{
|
||||
/* Hashes from SHA-1 and above */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_RIPEMD160) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
|
||||
0xFFFFFFF, /* Any PK alg */
|
||||
0xFFFFFFF, /* Any curve */
|
||||
1024, /* RSA min key len */
|
||||
};
|
||||
|
||||
/* See https://web.archive.org/web/20200921194007/tls.mbed.org/discussions/
|
||||
generic/howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
|
||||
|
|
@ -261,14 +210,20 @@ mbed_set_ssl_version_min_max(struct Curl_easy *data,
|
|||
/* TLS 1.0 and TLS 1.1 were dropped with mbedTLS 3.0.0 (2021). So, since
|
||||
* then, and before the introduction of TLS 1.3 in 3.6.0 (2024), this
|
||||
* function basically always sets TLS 1.2 as min/max, unless given
|
||||
* unsupported option values. */
|
||||
* unsupported option values, of if TLS 1.2 support is not compiled. */
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03020000
|
||||
int ver_min = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
|
||||
int ver_max = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
|
||||
#else
|
||||
/* mbedTLS 3.2.0 (2022) introduced new methods for setting TLS version */
|
||||
mbedtls_ssl_protocol_version ver_min = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
mbedtls_ssl_protocol_version ver_min =
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
MBEDTLS_SSL_VERSION_TLS1_2
|
||||
#else
|
||||
MBEDTLS_SSL_VERSION_TLS1_3
|
||||
#endif
|
||||
;
|
||||
mbedtls_ssl_protocol_version ver_max =
|
||||
#ifdef HAS_TLS13_SUPPORT
|
||||
MBEDTLS_SSL_VERSION_TLS1_3
|
||||
|
|
@ -280,26 +235,18 @@ mbed_set_ssl_version_min_max(struct Curl_easy *data,
|
|||
|
||||
switch(conn_config->version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
ver_min = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
ver_min = MBEDTLS_SSL_MINOR_VERSION_2;
|
||||
break;
|
||||
#else
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
#endif
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03020000
|
||||
ver_min = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
|
||||
#else
|
||||
ver_min = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
#ifdef HAS_TLS13_SUPPORT
|
||||
ver_min = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
|
|
@ -320,23 +267,16 @@ mbed_set_ssl_version_min_max(struct Curl_easy *data,
|
|||
break;
|
||||
#endif
|
||||
case CURL_SSLVERSION_MAX_TLSv1_2:
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03020000
|
||||
ver_max = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
|
||||
#else
|
||||
ver_max = MBEDTLS_SSL_VERSION_TLS1_2;
|
||||
#endif
|
||||
break;
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000
|
||||
case CURL_SSLVERSION_MAX_TLSv1_1:
|
||||
ver_max = MBEDTLS_SSL_MINOR_VERSION_2;
|
||||
break;
|
||||
case CURL_SSLVERSION_MAX_TLSv1_0:
|
||||
ver_max = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||
break;
|
||||
#else
|
||||
case CURL_SSLVERSION_MAX_TLSv1_1:
|
||||
case CURL_SSLVERSION_MAX_TLSv1_0:
|
||||
#endif
|
||||
case CURL_SSLVERSION_MAX_TLSv1_1:
|
||||
case CURL_SSLVERSION_MAX_TLSv1_0:
|
||||
default:
|
||||
failf(data, "mbedTLS: unsupported maximum TLS version value");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
|
@ -355,6 +295,8 @@ mbed_set_ssl_version_min_max(struct Curl_easy *data,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifndef CURL_DISABLE_CIPHER_SELECT
|
||||
/* TLS_ECJPAKE_WITH_AES_128_CCM_8 (0xC0FF) is marked experimental
|
||||
in mbedTLS. The number is not reserved by IANA nor is the
|
||||
cipher suite present in other SSL implementations. Provide
|
||||
|
|
@ -495,12 +437,14 @@ add_ciphers:
|
|||
mbedtls_ssl_conf_ciphersuites(&backend->config, backend->ciphersuites);
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_CERTINFO
|
||||
static void
|
||||
mbed_dump_cert_info(struct Curl_easy *data, const mbedtls_x509_crt *crt)
|
||||
{
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS) || \
|
||||
(MBEDTLS_VERSION_NUMBER >= 0x03000000 && defined(MBEDTLS_X509_REMOVE_INFO))
|
||||
(defined(MBEDTLS_X509_REMOVE_INFO))
|
||||
(void)data, (void)crt;
|
||||
#else
|
||||
const size_t bufsize = 16384;
|
||||
|
|
@ -558,7 +502,7 @@ static int mbed_verify_cb(void *ptr, mbedtls_x509_crt *crt,
|
|||
*flags &= ~MBEDTLS_X509_BADCERT_CN_MISMATCH;
|
||||
|
||||
if(*flags) {
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x03000000 || !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
char buf[128];
|
||||
mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", *flags);
|
||||
failf(data, "mbedTLS: %s", buf);
|
||||
|
|
@ -569,6 +513,7 @@ static int mbed_verify_cb(void *ptr, mbedtls_x509_crt *crt,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode
|
||||
mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
|
|
@ -586,6 +531,9 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
const char * const ssl_capath = conn_config->CApath;
|
||||
char * const ssl_cert = ssl_config->primary.clientcert;
|
||||
const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob;
|
||||
#ifdef MBEDTLS_PEM_PARSE_C
|
||||
const char* const ssl_cert_type = ssl_config->cert_type;
|
||||
#endif
|
||||
const char * const ssl_crlfile = ssl_config->primary.CRLfile;
|
||||
const char *hostname = connssl->peer.hostname;
|
||||
int ret = -1;
|
||||
|
|
@ -600,45 +548,49 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
#ifdef HAS_THREADING_SUPPORT
|
||||
mbedtls_ctr_drbg_init(&backend->ctr_drbg);
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex,
|
||||
&ts_entropy, NULL, 0);
|
||||
if(ret) {
|
||||
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
|
||||
-ret, errorbuf);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#else
|
||||
mbedtls_entropy_init(&backend->entropy);
|
||||
mbedtls_ctr_drbg_init(&backend->ctr_drbg);
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func,
|
||||
&backend->entropy, NULL, 0);
|
||||
if(ret) {
|
||||
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
|
||||
-ret, errorbuf);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#endif /* HAS_THREADING_SUPPORT */
|
||||
|
||||
/* Load the trusted CA */
|
||||
mbedtls_x509_crt_init(&backend->cacert);
|
||||
|
||||
if(ca_info_blob && verifypeer) {
|
||||
/* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
|
||||
terminated even when provided the exact length, forcing us to waste
|
||||
extra memory here. */
|
||||
unsigned char *newblob = Curl_memdup0(ca_info_blob->data,
|
||||
ca_info_blob->len);
|
||||
if(!newblob)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
ret = mbedtls_x509_crt_parse(&backend->cacert, newblob,
|
||||
ca_info_blob->len + 1);
|
||||
free(newblob);
|
||||
if(ca_info_blob && verifypeer)
|
||||
{
|
||||
#ifdef MBEDTLS_PEM_PARSE_C
|
||||
/* if DER or a null-terminated PEM just process using
|
||||
* mbedtls_x509_crt_parse().
|
||||
* */
|
||||
if(strcmp(ssl_cert_type, "DER") == 0
|
||||
|| ((char*)(ca_info_blob->data))[ca_info_blob->len - 1] == '\0'
|
||||
)
|
||||
{
|
||||
ret = mbedtls_x509_crt_parse(&backend->cacert,
|
||||
ca_info_blob->data,
|
||||
ca_info_blob->len);
|
||||
}
|
||||
else /* they say it's PEM and it's not null-terminated */
|
||||
{
|
||||
/* Unfortunately, mbedtls_x509_crt_parse() requires the data to
|
||||
be null-terminated if the data is PEM encoded (even when
|
||||
provided the exact length). The function accepts PEM or DER
|
||||
formats, but we can't assume if the user passed in a PEM
|
||||
format cert that it's null-terminated. */
|
||||
unsigned char *newblob = Curl_memdup0(ca_info_blob->data,
|
||||
ca_info_blob->len);
|
||||
if(!newblob)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ret = mbedtls_x509_crt_parse(&backend->cacert, newblob,
|
||||
ca_info_blob->len + 1);
|
||||
free(newblob);
|
||||
}
|
||||
#else
|
||||
/* DER encoded certs don't need to be null terminated
|
||||
because it's a binary format. So if we're not compiling
|
||||
with PEM_PARSE we can avoid the extra memory copies
|
||||
altogether. */
|
||||
ret = mbedtls_x509_crt_parse_der(&backend->cacert,
|
||||
ca_info_blob->data,
|
||||
ca_info_blob->len);
|
||||
#endif
|
||||
|
||||
if(ret < 0) {
|
||||
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
failf(data, "Error importing ca cert blob - mbedTLS: (-0x%04X) %s",
|
||||
|
|
@ -702,20 +654,46 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
}
|
||||
|
||||
if(ssl_cert_blob) {
|
||||
/* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
|
||||
terminated even when provided the exact length, forcing us to waste
|
||||
extra memory here. */
|
||||
unsigned char *newblob = Curl_memdup0(ssl_cert_blob->data,
|
||||
ssl_cert_blob->len);
|
||||
if(!newblob)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
ret = mbedtls_x509_crt_parse(&backend->clicert, newblob,
|
||||
ssl_cert_blob->len + 1);
|
||||
free(newblob);
|
||||
#ifdef MBEDTLS_PEM_PARSE_C
|
||||
/* if DER or a null-terminated PEM just process using
|
||||
* mbedtls_x509_crt_parse().
|
||||
* */
|
||||
if(strcmp(ssl_cert_type, "DER") == 0
|
||||
|| ((char*)(ssl_cert_blob->data))[ssl_cert_blob->len - 1] == '\0'
|
||||
)
|
||||
{
|
||||
ret = mbedtls_x509_crt_parse(&backend->clicert,
|
||||
ssl_cert_blob->data,
|
||||
ssl_cert_blob->len);
|
||||
}
|
||||
else /* they say it's PEM and it's not null-terminated */
|
||||
{
|
||||
/* Unfortunately, mbedtls_x509_crt_parse() requires the data to
|
||||
be null-terminated if the data is PEM encoded (even when
|
||||
provided the exact length). The function accepts PEM or DER
|
||||
formats, but we can't assume if the user passed in a PEM
|
||||
format cert that it's null-terminated. */
|
||||
unsigned char *newblob = Curl_memdup0(ssl_cert_blob->data,
|
||||
ssl_cert_blob->len);
|
||||
if(!newblob)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
ret = mbedtls_x509_crt_parse(&backend->clicert, newblob,
|
||||
ssl_cert_blob->len + 1);
|
||||
free(newblob);
|
||||
}
|
||||
#else
|
||||
/* DER encoded certs don't need to be null terminated
|
||||
because it's a binary format. So if we're not compiling
|
||||
with PEM_PARSE we can avoid the extra memory copies
|
||||
altogether. */
|
||||
ret = mbedtls_x509_crt_parse_der(&backend->clicert,
|
||||
ssl_cert_blob->data,
|
||||
ssl_cert_blob->len);
|
||||
#endif
|
||||
|
||||
if(ret) {
|
||||
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
failf(data, "Error reading client cert data %s - mbedTLS: (-0x%04X) %s",
|
||||
failf(data, "Error reading SSL cert blob %s - mbedTLS: (-0x%04X) %s",
|
||||
ssl_config->key, -ret, errorbuf);
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
}
|
||||
|
|
@ -727,15 +705,11 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
if(ssl_config->key || ssl_config->key_blob) {
|
||||
if(ssl_config->key) {
|
||||
#ifdef MBEDTLS_FS_IO
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key,
|
||||
ssl_config->key_passwd,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&backend->ctr_drbg);
|
||||
#else
|
||||
ret = mbedtls_pk_parse_keyfile(&backend->pk, ssl_config->key,
|
||||
ssl_config->key_passwd);
|
||||
#endif
|
||||
|
||||
if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) ||
|
||||
mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY)))
|
||||
ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
|
|
@ -756,17 +730,13 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
const unsigned char *key_data =
|
||||
(const unsigned char *)ssl_key_blob->data;
|
||||
const char *passwd = ssl_config->key_passwd;
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
|
||||
ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len,
|
||||
(const unsigned char *)passwd,
|
||||
passwd ? strlen(passwd) : 0,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&backend->ctr_drbg);
|
||||
#else
|
||||
ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len,
|
||||
(const unsigned char *)passwd,
|
||||
passwd ? strlen(passwd) : 0);
|
||||
#endif
|
||||
|
||||
if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) ||
|
||||
mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY)))
|
||||
ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
|
||||
|
|
@ -819,6 +789,19 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
#ifdef MBEDTLS_DEBUG_C
|
||||
/* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
|
||||
mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data);
|
||||
/* - 0 No debug
|
||||
* - 1 Error
|
||||
* - 2 State change
|
||||
* - 3 Informational
|
||||
* - 4 Verbose
|
||||
*/
|
||||
mbedtls_debug_set_threshold(4);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAS_SESSION_TICKETS) && MBEDTLS_VERSION_NUMBER >= 0x03060100
|
||||
/* New in mbedTLS 3.6.1, need to enable, default is now disabled */
|
||||
mbedtls_ssl_conf_tls13_enable_signal_new_session_tickets(&backend->config,
|
||||
|
|
@ -828,22 +811,25 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
/* Always let mbedTLS verify certificates, if verifypeer or verifyhost are
|
||||
* disabled we clear the corresponding error flags in the verify callback
|
||||
* function. That is also where we log verification errors. */
|
||||
|
||||
#ifndef CURL_DISABLE_CERTINFO
|
||||
mbedtls_ssl_conf_verify(&backend->config, mbed_verify_cb, cf);
|
||||
#endif
|
||||
mbedtls_ssl_conf_authmode(&backend->config, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
|
||||
mbedtls_ssl_init(&backend->ssl);
|
||||
backend->initialized = TRUE;
|
||||
|
||||
/* new profile with RSA min key len = 1024 ... */
|
||||
/* use the default secure profile baked into mbedTLS */
|
||||
mbedtls_ssl_conf_cert_profile(&backend->config,
|
||||
&mbedtls_x509_crt_profile_fr);
|
||||
&mbedtls_x509_crt_profile_next);
|
||||
|
||||
ret = mbed_set_ssl_version_min_max(data, backend, conn_config);
|
||||
if(ret != CURLE_OK)
|
||||
return ret;
|
||||
|
||||
mbedtls_ssl_conf_rng(&backend->config, mbedtls_ctr_drbg_random,
|
||||
&backend->ctr_drbg);
|
||||
&rng.drbg);
|
||||
|
||||
ret = mbedtls_ssl_setup(&backend->ssl, &backend->config);
|
||||
if(ret) {
|
||||
|
|
@ -858,6 +844,13 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
mbedtls_bio_cf_read,
|
||||
NULL /* rev_timeout() */);
|
||||
|
||||
|
||||
/* Allow the user to select TLS 1.2/1.3 ciphersuites.
|
||||
If the user doesn't supply ciphersuites, the default
|
||||
secure ciphersuites are used (thus no need to call
|
||||
mbedtls_ssl_conf_ciphersuites() ).
|
||||
*/
|
||||
#ifndef CURL_DISABLE_CIPHER_SELECT
|
||||
#ifndef HAS_TLS13_SUPPORT
|
||||
if(conn_config->cipher_list) {
|
||||
CURLcode result = mbed_set_selected_ciphers(data, backend,
|
||||
|
|
@ -878,7 +871,7 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
mbedtls_ssl_conf_ciphersuites(&backend->config,
|
||||
mbedtls_ssl_list_ciphersuites());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MBEDTLS_SSL_RENEGOTIATION
|
||||
mbedtls_ssl_conf_renegotiation(&backend->config,
|
||||
|
|
@ -960,18 +953,6 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef MBEDTLS_DEBUG
|
||||
/* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
|
||||
mbedtls_ssl_conf_dbg(&backend->config, mbed_debug, data);
|
||||
/* - 0 No debug
|
||||
* - 1 Error
|
||||
* - 2 State change
|
||||
* - 3 Informational
|
||||
* - 4 Verbose
|
||||
*/
|
||||
mbedtls_debug_set_threshold(4);
|
||||
#endif
|
||||
|
||||
/* give application a chance to interfere with mbedTLS set up. */
|
||||
if(data->set.ssl.fsslctx) {
|
||||
CURLcode result = (*data->set.ssl.fsslctx)(data, &backend->config,
|
||||
|
|
@ -994,12 +975,14 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
struct mbed_ssl_backend_data *backend =
|
||||
(struct mbed_ssl_backend_data *)connssl->backend;
|
||||
#ifdef MBEDTLS_PK_WRITE_C
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf) ?
|
||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
|
||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
|
||||
#else
|
||||
const char * const pinnedpubkey = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(backend);
|
||||
|
|
@ -1030,7 +1013,9 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03020000
|
||||
|
||||
#if (MBEDTLS_VERSION_NUMBER >= 0x03020000) && \
|
||||
!defined(CURL_DISABLE_VERBOSE_STRINGS) && !defined(CURL_DISABLE_CIPHER_SELECT)
|
||||
{
|
||||
char cipher_str[64];
|
||||
uint16_t cipher_id;
|
||||
|
|
@ -1045,6 +1030,7 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
mbedtls_ssl_get_version(&backend->ssl));
|
||||
#endif
|
||||
|
||||
#ifdef MBEDTLS_PK_WRITE_C
|
||||
if(pinnedpubkey) {
|
||||
int size;
|
||||
CURLcode result;
|
||||
|
|
@ -1053,12 +1039,7 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
unsigned char *pubkey = NULL;
|
||||
|
||||
peercert = mbedtls_ssl_get_peer_cert(&backend->ssl);
|
||||
#if MBEDTLS_VERSION_NUMBER == 0x03000000
|
||||
if(!peercert || !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p) ||
|
||||
!peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len)) {
|
||||
#else
|
||||
if(!peercert || !peercert->raw.p || !peercert->raw.len) {
|
||||
#endif
|
||||
failf(data, "Failed due to missing peer certificate");
|
||||
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||
}
|
||||
|
|
@ -1080,24 +1061,13 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
/* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
|
||||
needs a non-const key, for now.
|
||||
https://github.com/Mbed-TLS/mbedtls/issues/396 */
|
||||
#if MBEDTLS_VERSION_NUMBER == 0x03000000
|
||||
if(mbedtls_x509_crt_parse_der(p,
|
||||
peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p),
|
||||
peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len))) {
|
||||
#else
|
||||
if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
|
||||
#endif
|
||||
failf(data, "Failed copying peer certificate");
|
||||
result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||
goto pinnedpubkey_error;
|
||||
}
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER == 0x03000000
|
||||
size = mbedtls_pk_write_pubkey_der(&p->MBEDTLS_PRIVATE(pk), pubkey,
|
||||
PUB_DER_MAX_BYTES);
|
||||
#else
|
||||
size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
|
||||
#endif
|
||||
|
||||
if(size <= 0) {
|
||||
failf(data, "Failed copying public key from peer certificate");
|
||||
|
|
@ -1117,6 +1087,7 @@ pinnedpubkey_error:
|
|||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_ALPN_MBEDTLS
|
||||
if(connssl->alpn) {
|
||||
|
|
@ -1359,9 +1330,6 @@ static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
mbedtls_ssl_config_free(&backend->config);
|
||||
mbedtls_ssl_free(&backend->ssl);
|
||||
mbedtls_ctr_drbg_free(&backend->ctr_drbg);
|
||||
#ifndef HAS_THREADING_SUPPORT
|
||||
mbedtls_entropy_free(&backend->entropy);
|
||||
#endif /* HAS_THREADING_SUPPORT */
|
||||
backend->initialized = FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1427,29 +1395,24 @@ static CURLcode mbedtls_random(struct Curl_easy *data,
|
|||
unsigned char *entropy, size_t length)
|
||||
{
|
||||
#ifdef MBEDTLS_CTR_DRBG_C
|
||||
int ret;
|
||||
mbedtls_entropy_context ctr_entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_entropy_init(&ctr_entropy);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
(void)data;
|
||||
int ret = -1;
|
||||
char errorbuf[128];
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
|
||||
&ctr_entropy, NULL, 0);
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
ret = mbedtls_ctr_drbg_random(&rng.drbg, entropy, length);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
ret = mbedtls_hmac_drbg_random(&rng.drbg, entropy, length);
|
||||
#else
|
||||
#error "No DRBG available"
|
||||
#endif
|
||||
|
||||
if(!ret)
|
||||
ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length);
|
||||
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_entropy_free(&ctr_entropy);
|
||||
if(ret) {
|
||||
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
failf(data, "mbedtls_ctr_drbg_random returned (-0x%04X) %s",
|
||||
-ret, errorbuf);
|
||||
}
|
||||
|
||||
return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT;
|
||||
#elif defined(MBEDTLS_HAVEGE_C)
|
||||
mbedtls_havege_state hs;
|
||||
mbedtls_havege_init(&hs);
|
||||
mbedtls_havege_random(&hs, entropy, length);
|
||||
mbedtls_havege_free(&hs);
|
||||
return CURLE_OK;
|
||||
#else
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
|
|
@ -1516,34 +1479,78 @@ static CURLcode mbedtls_connect(struct Curl_cfilter *cf,
|
|||
*/
|
||||
static int mbedtls_init(void)
|
||||
{
|
||||
if(!Curl_mbedtlsthreadlock_thread_setup())
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS)
|
||||
return 0;
|
||||
#ifdef HAS_THREADING_SUPPORT
|
||||
entropy_init_mutex(&ts_entropy);
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO || MBEDTLS_SSL_PROTO_TLS1_3 */
|
||||
|
||||
|
||||
/* initialize the RNG context & entropy */
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
mbedtls_ctr_drbg_init(&rng.drbg);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
mbedtls_hmac_drbg_init(&rng.drbg);
|
||||
#else
|
||||
#error "No DRBG available"
|
||||
#endif
|
||||
#ifdef HAS_PSA_SUPPORT
|
||||
{
|
||||
int ret;
|
||||
#ifdef HAS_THREADING_SUPPORT
|
||||
Curl_mbedtlsthreadlock_lock_function(0);
|
||||
|
||||
mbedtls_entropy_init(&rng.entropy);
|
||||
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
int ret = mbedtls_ctr_drbg_seed(&rng.drbg,
|
||||
mbedtls_entropy_func, &rng.entropy,
|
||||
NULL, 0);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;
|
||||
#elif defined(MBEDTLS_SHA512_C)
|
||||
const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA512;
|
||||
#else
|
||||
#error "No message digest available for HMAC_DRBG"
|
||||
#endif
|
||||
ret = psa_crypto_init();
|
||||
#ifdef HAS_THREADING_SUPPORT
|
||||
Curl_mbedtlsthreadlock_unlock_function(0);
|
||||
#endif
|
||||
if(ret != PSA_SUCCESS)
|
||||
return 0;
|
||||
int ret = mbedtls_hmac_drbg_seed(&rng.drbg,
|
||||
mbedtls_md_info_from_type(md_type),
|
||||
mbedtls_entropy_func, &rng.entropy,
|
||||
NULL, 0);
|
||||
#else /* !defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_HMAC_DRBG_C) */
|
||||
#error "No DRBG available"
|
||||
#endif /* !defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_HMAC_DRBG_C) */
|
||||
|
||||
if(ret != 0) {
|
||||
//TODO: write an error without a `data` param
|
||||
//failf(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n",
|
||||
// (unsigned int)-ret);
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAS_PSA_SUPPORT */
|
||||
|
||||
/* To prevent an adversary from reading your random data,
|
||||
you can enable prediction resistance.
|
||||
|
||||
Entropy is gathered before each mbedtls_ctr_drbg_random() call.
|
||||
Only use this if you have ample supply of good entropy.*/
|
||||
mbedtls_ctr_drbg_set_prediction_resistance(&rng.drbg,
|
||||
MBEDTLS_CTR_DRBG_PR_ON);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void mbedtls_cleanup(void)
|
||||
{
|
||||
#ifdef HAS_THREADING_SUPPORT
|
||||
entropy_cleanup_mutex(&ts_entropy);
|
||||
#if (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3))
|
||||
mbedtls_psa_crypto_free();
|
||||
#endif
|
||||
(void)Curl_mbedtlsthreadlock_thread_cleanup();
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
mbedtls_ctr_drbg_free(&rng.drbg);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
mbedtls_hmac_drbg_free(&rng.drbg);
|
||||
#else
|
||||
#error "No DRBG available"
|
||||
#endif
|
||||
|
||||
mbedtls_entropy_free(&rng.entropy);
|
||||
}
|
||||
|
||||
static bool mbedtls_data_pending(struct Curl_cfilter *cf,
|
||||
|
|
@ -1564,17 +1571,9 @@ static CURLcode mbedtls_sha256sum(const unsigned char *input,
|
|||
size_t sha256len UNUSED_PARAM)
|
||||
{
|
||||
(void)sha256len;
|
||||
#if MBEDTLS_VERSION_NUMBER < 0x02070000
|
||||
mbedtls_sha256(input, inputlen, sha256sum, 0);
|
||||
#else
|
||||
/* returns 0 on success, otherwise failure */
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
if(mbedtls_sha256(input, inputlen, sha256sum, 0) != 0)
|
||||
#else
|
||||
if(mbedtls_sha256_ret(input, inputlen, sha256sum, 0) != 0)
|
||||
#endif
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
#endif
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1593,14 +1592,21 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
|
|||
|
||||
SSLSUPP_CA_PATH |
|
||||
SSLSUPP_CAINFO_BLOB |
|
||||
#ifndef CURL_DISABLE_CERTINFO
|
||||
SSLSUPP_CERTINFO |
|
||||
#endif
|
||||
#ifdef MBEDTLS_PK_WRITE_C
|
||||
SSLSUPP_PINNEDPUBKEY |
|
||||
#endif
|
||||
SSLSUPP_SSL_CTX |
|
||||
#ifdef HAS_TLS13_SUPPORT
|
||||
#if defined(HAS_TLS13_SUPPORT) && !defined(CURL_DISABLE_CIPHER_SELECT)
|
||||
SSLSUPP_TLS13_CIPHERSUITES |
|
||||
#endif
|
||||
SSLSUPP_HTTPS_PROXY |
|
||||
SSLSUPP_CIPHER_LIST,
|
||||
SSLSUPP_HTTPS_PROXY
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(CURL_DISABLE_CIPHER_SELECT)
|
||||
| SSLSUPP_CIPHER_LIST
|
||||
#endif
|
||||
,
|
||||
|
||||
sizeof(struct mbed_ssl_backend_data),
|
||||
|
||||
|
|
|
|||
|
|
@ -1,134 +0,0 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#if defined(USE_MBEDTLS) && \
|
||||
((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
|
||||
defined(_WIN32))
|
||||
|
||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||
# include <pthread.h>
|
||||
# define MBEDTLS_MUTEX_T pthread_mutex_t
|
||||
#elif defined(_WIN32)
|
||||
# define MBEDTLS_MUTEX_T HANDLE
|
||||
#endif
|
||||
|
||||
#include "mbedtls_threadlock.h"
|
||||
#include "../curl_printf.h"
|
||||
#include "../curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "../memdebug.h"
|
||||
|
||||
/* number of thread locks */
|
||||
#define NUMT 2
|
||||
|
||||
/* This array will store all of the mutexes available to Mbedtls. */
|
||||
static MBEDTLS_MUTEX_T *mutex_buf = NULL;
|
||||
|
||||
int Curl_mbedtlsthreadlock_thread_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mutex_buf = calloc(1, NUMT * sizeof(MBEDTLS_MUTEX_T));
|
||||
if(!mutex_buf)
|
||||
return 0; /* error, no number of threads defined */
|
||||
|
||||
for(i = 0; i < NUMT; i++) {
|
||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||
if(pthread_mutex_init(&mutex_buf[i], NULL))
|
||||
return 0; /* pthread_mutex_init failed */
|
||||
#elif defined(_WIN32)
|
||||
mutex_buf[i] = CreateMutex(0, FALSE, 0);
|
||||
if(mutex_buf[i] == 0)
|
||||
return 0; /* CreateMutex failed */
|
||||
#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
|
||||
}
|
||||
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
int Curl_mbedtlsthreadlock_thread_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!mutex_buf)
|
||||
return 0; /* error, no threads locks defined */
|
||||
|
||||
for(i = 0; i < NUMT; i++) {
|
||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||
if(pthread_mutex_destroy(&mutex_buf[i]))
|
||||
return 0; /* pthread_mutex_destroy failed */
|
||||
#elif defined(_WIN32)
|
||||
if(!CloseHandle(mutex_buf[i]))
|
||||
return 0; /* CloseHandle failed */
|
||||
#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
|
||||
}
|
||||
free(mutex_buf);
|
||||
mutex_buf = NULL;
|
||||
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
int Curl_mbedtlsthreadlock_lock_function(int n)
|
||||
{
|
||||
if(n < NUMT) {
|
||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||
if(pthread_mutex_lock(&mutex_buf[n])) {
|
||||
DEBUGF(fprintf(stderr,
|
||||
"Error: mbedtlsthreadlock_lock_function failed\n"));
|
||||
return 0; /* pthread_mutex_lock failed */
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
if(WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED) {
|
||||
DEBUGF(fprintf(stderr,
|
||||
"Error: mbedtlsthreadlock_lock_function failed\n"));
|
||||
return 0; /* pthread_mutex_lock failed */
|
||||
}
|
||||
#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
int Curl_mbedtlsthreadlock_unlock_function(int n)
|
||||
{
|
||||
if(n < NUMT) {
|
||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||
if(pthread_mutex_unlock(&mutex_buf[n])) {
|
||||
DEBUGF(fprintf(stderr,
|
||||
"Error: mbedtlsthreadlock_unlock_function failed\n"));
|
||||
return 0; /* pthread_mutex_unlock failed */
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
if(!ReleaseMutex(mutex_buf[n])) {
|
||||
DEBUGF(fprintf(stderr,
|
||||
"Error: mbedtlsthreadlock_unlock_function failed\n"));
|
||||
return 0; /* pthread_mutex_lock failed */
|
||||
}
|
||||
#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
#endif /* USE_MBEDTLS */
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
#ifndef HEADER_CURL_MBEDTLS_THREADLOCK_H
|
||||
#define HEADER_CURL_MBEDTLS_THREADLOCK_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "../curl_setup.h"
|
||||
|
||||
#ifdef USE_MBEDTLS
|
||||
|
||||
#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
|
||||
defined(_WIN32)
|
||||
|
||||
int Curl_mbedtlsthreadlock_thread_setup(void);
|
||||
int Curl_mbedtlsthreadlock_thread_cleanup(void);
|
||||
int Curl_mbedtlsthreadlock_lock_function(int n);
|
||||
int Curl_mbedtlsthreadlock_unlock_function(int n);
|
||||
|
||||
#else
|
||||
|
||||
#define Curl_mbedtlsthreadlock_thread_setup() 1
|
||||
#define Curl_mbedtlsthreadlock_thread_cleanup() 1
|
||||
#define Curl_mbedtlsthreadlock_lock_function(x) 1
|
||||
#define Curl_mbedtlsthreadlock_unlock_function(x) 1
|
||||
|
||||
#endif /* (USE_THREADS_POSIX && HAVE_PTHREAD_H) || _WIN32 */
|
||||
|
||||
#endif /* USE_MBEDTLS */
|
||||
|
||||
#endif /* HEADER_CURL_MBEDTLS_THREADLOCK_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue