wolfssl: simplify Curl_wssl_ctx_init

by splitting out functions for client certificate and setting min/max
TLS version

Closes #18402
This commit is contained in:
Daniel Stenberg 2025-08-26 15:15:19 +02:00
parent 0a96b878f7
commit 0f3f6e3a93
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -938,6 +938,163 @@ wssl_legacy_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version)
#define wolfSSL_CTX_set_max_proto_version wssl_legacy_CTX_set_max_proto_version
#endif
static CURLcode client_certificate(struct Curl_easy *data,
struct ssl_config_data *ssl_config,
struct wssl_ctx *wctx)
{
/* Load the client certificate, and private key */
#ifndef NO_FILESYSTEM
if(ssl_config->primary.cert_blob || ssl_config->primary.clientcert) {
const char *cert_file = ssl_config->primary.clientcert;
const char *key_file = ssl_config->key;
const struct curl_blob *cert_blob = ssl_config->primary.cert_blob;
const struct curl_blob *key_blob = ssl_config->key_blob;
int file_type = wssl_do_file_type(ssl_config->cert_type);
int rc;
switch(file_type) {
case WOLFSSL_FILETYPE_PEM:
rc = cert_blob ?
wolfSSL_CTX_use_certificate_chain_buffer(wctx->ssl_ctx,
cert_blob->data,
(long)cert_blob->len) :
wolfSSL_CTX_use_certificate_chain_file(wctx->ssl_ctx, cert_file);
break;
case WOLFSSL_FILETYPE_ASN1:
rc = cert_blob ?
wolfSSL_CTX_use_certificate_buffer(wctx->ssl_ctx, cert_blob->data,
(long)cert_blob->len, file_type) :
wolfSSL_CTX_use_certificate_file(wctx->ssl_ctx, cert_file, file_type);
break;
default:
failf(data, "unknown cert type");
return CURLE_BAD_FUNCTION_ARGUMENT;
}
if(rc != 1) {
failf(data, "unable to use client certificate");
return CURLE_SSL_CONNECT_ERROR;
}
if(!key_blob && !key_file) {
key_blob = cert_blob;
key_file = cert_file;
}
else
file_type = wssl_do_file_type(ssl_config->key_type);
rc = key_blob ?
wolfSSL_CTX_use_PrivateKey_buffer(wctx->ssl_ctx, key_blob->data,
(long)key_blob->len, file_type) :
wolfSSL_CTX_use_PrivateKey_file(wctx->ssl_ctx, key_file, file_type);
if(rc != 1) {
failf(data, "unable to set private key");
return CURLE_SSL_CONNECT_ERROR;
}
}
#else /* NO_FILESYSTEM */
if(ssl_config->primary.cert_blob) {
const struct curl_blob *cert_blob = ssl_config->primary.cert_blob;
const struct curl_blob *key_blob = ssl_config->key_blob;
int file_type = wssl_do_file_type(ssl_config->cert_type);
int rc;
switch(file_type) {
case WOLFSSL_FILETYPE_PEM:
rc = wolfSSL_CTX_use_certificate_chain_buffer(wctx->ssl_ctx,
cert_blob->data,
(long)cert_blob->len);
break;
case WOLFSSL_FILETYPE_ASN1:
rc = wolfSSL_CTX_use_certificate_buffer(wctx->ssl_ctx, cert_blob->data,
(long)cert_blob->len, file_type);
break;
default:
failf(data, "unknown cert type");
return CURLE_BAD_FUNCTION_ARGUMENT;
}
if(rc != 1) {
failf(data, "unable to use client certificate");
return CURLE_SSL_CONNECT_ERROR;
}
if(!key_blob)
key_blob = cert_blob;
else
file_type = wssl_do_file_type(ssl_config->key_type);
if(wolfSSL_CTX_use_PrivateKey_buffer(wctx->ssl_ctx, key_blob->data,
(long)key_blob->len,
file_type) != 1) {
failf(data, "unable to set private key");
return CURLE_SSL_CONNECT_ERROR;
}
}
#endif /* !NO_FILESYSTEM */
return CURLE_OK;
}
static CURLcode ssl_version(struct Curl_easy *data,
struct ssl_primary_config *conn_config,
struct wssl_ctx *wctx)
{
int res;
switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
res = wolfSSL_CTX_set_min_proto_version(wctx->ssl_ctx, TLS1_VERSION);
break;
case CURL_SSLVERSION_TLSv1_1:
res = wolfSSL_CTX_set_min_proto_version(wctx->ssl_ctx, TLS1_1_VERSION);
break;
case CURL_SSLVERSION_TLSv1_2:
res = wolfSSL_CTX_set_min_proto_version(wctx->ssl_ctx, TLS1_2_VERSION);
break;
#ifdef WOLFSSL_TLS13
case CURL_SSLVERSION_TLSv1_3:
res = wolfSSL_CTX_set_min_proto_version(wctx->ssl_ctx, TLS1_3_VERSION);
break;
#endif
default:
failf(data, "wolfSSL: unsupported minimum TLS version value");
return CURLE_SSL_CONNECT_ERROR;
}
if(res != WOLFSSL_SUCCESS) {
failf(data, "wolfSSL: failed set the minimum TLS version");
return CURLE_SSL_CONNECT_ERROR;
}
switch(conn_config->version_max) {
#ifdef WOLFSSL_TLS13
case CURL_SSLVERSION_MAX_TLSv1_3:
res = wolfSSL_CTX_set_max_proto_version(wctx->ssl_ctx, TLS1_3_VERSION);
break;
#endif
case CURL_SSLVERSION_MAX_TLSv1_2:
res = wolfSSL_CTX_set_max_proto_version(wctx->ssl_ctx, TLS1_2_VERSION);
break;
case CURL_SSLVERSION_MAX_TLSv1_1:
res = wolfSSL_CTX_set_max_proto_version(wctx->ssl_ctx, TLS1_1_VERSION);
break;
case CURL_SSLVERSION_MAX_TLSv1_0:
res = wolfSSL_CTX_set_max_proto_version(wctx->ssl_ctx, TLS1_VERSION);
break;
case CURL_SSLVERSION_MAX_DEFAULT:
case CURL_SSLVERSION_MAX_NONE:
res = WOLFSSL_SUCCESS;
break;
default:
failf(data, "wolfSSL: unsupported maximum TLS version value");
return CURLE_SSL_CONNECT_ERROR;
}
if(res != WOLFSSL_SUCCESS) {
failf(data, "wolfSSL: failed set the maximum TLS version");
return CURLE_SSL_CONNECT_ERROR;
}
return CURLE_OK;
}
#define QUIC_CIPHERS \
"TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \
"POLY1305_SHA256:TLS_AES_128_CCM_SHA256"
@ -957,7 +1114,6 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx,
struct ssl_primary_config *conn_config;
WOLFSSL_METHOD* req_method = NULL;
struct alpn_spec alpns;
int res;
char *curves;
#ifdef WOLFSSL_HAVE_KYBER
word16 pqkem = 0;
@ -998,63 +1154,9 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx,
goto out;
}
switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
res = wolfSSL_CTX_set_min_proto_version(wctx->ssl_ctx, TLS1_VERSION);
break;
case CURL_SSLVERSION_TLSv1_1:
res = wolfSSL_CTX_set_min_proto_version(wctx->ssl_ctx, TLS1_1_VERSION);
break;
case CURL_SSLVERSION_TLSv1_2:
res = wolfSSL_CTX_set_min_proto_version(wctx->ssl_ctx, TLS1_2_VERSION);
break;
#ifdef WOLFSSL_TLS13
case CURL_SSLVERSION_TLSv1_3:
res = wolfSSL_CTX_set_min_proto_version(wctx->ssl_ctx, TLS1_3_VERSION);
break;
#endif
default:
failf(data, "wolfSSL: unsupported minimum TLS version value");
result = CURLE_SSL_CONNECT_ERROR;
result = ssl_version(data, conn_config, wctx);
if(result)
goto out;
}
if(res != WOLFSSL_SUCCESS) {
failf(data, "wolfSSL: failed set the minimum TLS version");
result = CURLE_SSL_CONNECT_ERROR;
goto out;
}
switch(conn_config->version_max) {
#ifdef WOLFSSL_TLS13
case CURL_SSLVERSION_MAX_TLSv1_3:
res = wolfSSL_CTX_set_max_proto_version(wctx->ssl_ctx, TLS1_3_VERSION);
break;
#endif
case CURL_SSLVERSION_MAX_TLSv1_2:
res = wolfSSL_CTX_set_max_proto_version(wctx->ssl_ctx, TLS1_2_VERSION);
break;
case CURL_SSLVERSION_MAX_TLSv1_1:
res = wolfSSL_CTX_set_max_proto_version(wctx->ssl_ctx, TLS1_1_VERSION);
break;
case CURL_SSLVERSION_MAX_TLSv1_0:
res = wolfSSL_CTX_set_max_proto_version(wctx->ssl_ctx, TLS1_VERSION);
break;
case CURL_SSLVERSION_MAX_DEFAULT:
case CURL_SSLVERSION_MAX_NONE:
res = WOLFSSL_SUCCESS;
break;
default:
failf(data, "wolfSSL: unsupported maximum TLS version value");
result = CURLE_SSL_CONNECT_ERROR;
goto out;
}
if(res != WOLFSSL_SUCCESS) {
failf(data, "wolfSSL: failed set the maximum TLS version");
result = CURLE_SSL_CONNECT_ERROR;
goto out;
}
#ifndef WOLFSSL_TLS13
{
@ -1129,100 +1231,9 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx,
}
}
/* Load the client certificate, and private key */
#ifndef NO_FILESYSTEM
if(ssl_config->primary.cert_blob || ssl_config->primary.clientcert) {
const char *cert_file = ssl_config->primary.clientcert;
const char *key_file = ssl_config->key;
const struct curl_blob *cert_blob = ssl_config->primary.cert_blob;
const struct curl_blob *key_blob = ssl_config->key_blob;
int file_type = wssl_do_file_type(ssl_config->cert_type);
int rc;
switch(file_type) {
case WOLFSSL_FILETYPE_PEM:
rc = cert_blob ?
wolfSSL_CTX_use_certificate_chain_buffer(wctx->ssl_ctx,
cert_blob->data,
(long)cert_blob->len) :
wolfSSL_CTX_use_certificate_chain_file(wctx->ssl_ctx, cert_file);
break;
case WOLFSSL_FILETYPE_ASN1:
rc = cert_blob ?
wolfSSL_CTX_use_certificate_buffer(wctx->ssl_ctx, cert_blob->data,
(long)cert_blob->len, file_type) :
wolfSSL_CTX_use_certificate_file(wctx->ssl_ctx, cert_file, file_type);
break;
default:
failf(data, "unknown cert type");
result = CURLE_BAD_FUNCTION_ARGUMENT;
goto out;
}
if(rc != 1) {
failf(data, "unable to use client certificate");
result = CURLE_SSL_CONNECT_ERROR;
goto out;
}
if(!key_blob && !key_file) {
key_blob = cert_blob;
key_file = cert_file;
}
else
file_type = wssl_do_file_type(ssl_config->key_type);
rc = key_blob ?
wolfSSL_CTX_use_PrivateKey_buffer(wctx->ssl_ctx, key_blob->data,
(long)key_blob->len, file_type) :
wolfSSL_CTX_use_PrivateKey_file(wctx->ssl_ctx, key_file, file_type);
if(rc != 1) {
failf(data, "unable to set private key");
result = CURLE_SSL_CONNECT_ERROR;
goto out;
}
}
#else /* NO_FILESYSTEM */
if(ssl_config->primary.cert_blob) {
const struct curl_blob *cert_blob = ssl_config->primary.cert_blob;
const struct curl_blob *key_blob = ssl_config->key_blob;
int file_type = wssl_do_file_type(ssl_config->cert_type);
int rc;
switch(file_type) {
case WOLFSSL_FILETYPE_PEM:
rc = wolfSSL_CTX_use_certificate_chain_buffer(wctx->ssl_ctx,
cert_blob->data,
(long)cert_blob->len);
break;
case WOLFSSL_FILETYPE_ASN1:
rc = wolfSSL_CTX_use_certificate_buffer(wctx->ssl_ctx, cert_blob->data,
(long)cert_blob->len, file_type);
break;
default:
failf(data, "unknown cert type");
result = CURLE_BAD_FUNCTION_ARGUMENT;
goto out;
}
if(rc != 1) {
failf(data, "unable to use client certificate");
result = CURLE_SSL_CONNECT_ERROR;
goto out;
}
if(!key_blob)
key_blob = cert_blob;
else
file_type = wssl_do_file_type(ssl_config->key_type);
if(wolfSSL_CTX_use_PrivateKey_buffer(wctx->ssl_ctx, key_blob->data,
(long)key_blob->len,
file_type) != 1) {
failf(data, "unable to set private key");
result = CURLE_SSL_CONNECT_ERROR;
goto out;
}
}
#endif /* !NO_FILESYSTEM */
result = client_certificate(data, ssl_config, wctx);
if(result)
goto out;
/* SSL always tries to verify the peer, this only says whether it should
* fail to connect if the verification fails, or if it should continue