gtls: add return checks and optimize the code

This commit does the following things:

1. Update the description of gtls_init()

2. In gtls_client_init(), check the invaild SSLVERSION at first. Note
   that this part refactors the duplicate/incompatible checks and removes
   the useless local variable `sni`.

3. Check the return value of gnutls_ocsp_resp_init(). Although the
   original code is safe because gnutls_ocsp_resp_import() will check
   the validity of `ocsp_resp`, it is better to catch the error in time
   and record the proper message to output log.

Closes #19366
This commit is contained in:
x2018 2025-11-05 02:16:54 +08:00 committed by Daniel Stenberg
parent dd71f61ea2
commit 2db36f11b8
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -72,7 +72,6 @@ static void tls_log_func(int level, const char *str)
curl_mfprintf(stderr, "|<%d>| %s", level, str);
}
#endif
static bool gtls_inited = FALSE;
#if !defined(GNUTLS_VERSION_NUMBER) || (GNUTLS_VERSION_NUMBER < 0x03010a)
#error "too old GnuTLS version"
@ -149,33 +148,31 @@ static ssize_t gtls_pull(void *s, void *buf, size_t blen)
return (ssize_t)nread;
}
/* gtls_init()
/**
* gtls_init()
*
* Global GnuTLS init, called from Curl_ssl_init(). This calls functions that
* are not thread-safe and thus this function itself is not thread-safe and
* must only be called from within curl_global_init() to keep the thread
* situation under control!
* are not thread-safe (It is thread safe since GnuTLS 3.3.0) and thus this
* function itself is not thread-safe and must only be called from within
* curl_global_init() to keep the thread situation under control!
*
* @retval 0 error initializing SSL
* @retval 1 SSL initialized successfully
*/
static int gtls_init(void)
{
int ret = 1;
if(!gtls_inited) {
ret = gnutls_global_init() ? 0 : 1;
ret = gnutls_global_init() ? 0 : 1;
#ifdef GTLSDEBUG
gnutls_global_set_log_function(tls_log_func);
gnutls_global_set_log_level(2);
gnutls_global_set_log_function(tls_log_func);
gnutls_global_set_log_level(2);
#endif
gtls_inited = TRUE;
}
return ret;
}
static void gtls_cleanup(void)
{
if(gtls_inited) {
gnutls_global_deinit();
gtls_inited = FALSE;
}
gnutls_global_deinit();
}
#ifndef CURL_DISABLE_VERBOSE_STRINGS
@ -860,20 +857,15 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf,
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
unsigned int init_flags;
int rc;
bool sni = TRUE; /* default is SNI enabled */
const char *prioritylist;
bool tls13support;
CURLcode result;
if(!gtls_inited)
gtls_init();
if(config->version == CURL_SSLVERSION_SSLv2) {
failf(data, "GnuTLS does not support SSLv2");
if(config->version == CURL_SSLVERSION_SSLv2 ||
config->version == CURL_SSLVERSION_SSLv3) {
failf(data, "GnuTLS does not support SSLv2 or SSLv3");
return CURLE_SSL_CONNECT_ERROR;
}
else if(config->version == CURL_SSLVERSION_SSLv3)
sni = FALSE; /* SSLv3 has no SNI */
/* allocate a shared creds struct */
result = Curl_gtls_shared_creds_create(data, &gtls->shared_creds);
@ -940,7 +932,7 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf,
return CURLE_SSL_CONNECT_ERROR;
}
if(sni && peer->sni) {
if(peer->sni) {
if(gnutls_server_name_set(gtls->session, GNUTLS_NAME_DNS,
peer->sni, strlen(peer->sni)) < 0) {
failf(data, "Failed to set SNI");
@ -956,16 +948,6 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf,
/* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */
tls13support = !!gnutls_check_version("3.6.5");
/* Ensure +SRP comes at the *end* of all relevant strings so that it can be
* removed if a runtime error indicates that SRP is not supported by this
* GnuTLS version */
if(config->version == CURL_SSLVERSION_SSLv2 ||
config->version == CURL_SSLVERSION_SSLv3) {
failf(data, "GnuTLS does not support SSLv2 or SSLv3");
return CURLE_SSL_CONNECT_ERROR;
}
if(config->version == CURL_SSLVERSION_TLSv1_3) {
if(!tls13support) {
failf(data, "This GnuTLS installation does not support TLS 1.3");
@ -1159,7 +1141,7 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
if(sess_reuse_cb) {
result = sess_reuse_cb(cf, data, &alpns, scs, &do_early_data);
if(result)
goto out;
goto out;
}
if(do_early_data) {
/* We only try the ALPN protocol the session used before,
@ -1452,7 +1434,12 @@ static CURLcode gtls_verify_ocsp_status(struct Curl_easy *data,
goto out;
}
gnutls_ocsp_resp_init(&ocsp_resp);
rc = gnutls_ocsp_resp_init(&ocsp_resp);
if(rc < 0) {
failf(data, "Failed to initialize OCSP response object");
result = CURLE_SSL_INVALIDCERTSTATUS;
goto out;
}
rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
if(rc < 0) {