#include <wolfssl/version.h>
#include <wolfssl/options.h>
+#if LIBWOLFSSL_VERSION_HEX < 0x03004006 /* wolfSSL 3.4.6 (2015) */
+#error "wolfSSL version should be at least 3.4.6"
+#endif
+
/* To determine what functions are available we rely on one or both of:
- the user's options.h generated by wolfSSL
- the symbols detected by curl's configure
}
#endif
+#if LIBWOLFSSL_VERSION_HEX < 0x04002000 /* 4.2.0 (2019) */
+static int
+wssl_legacy_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
+{
+ int res;
+ switch(version) {
+ default:
+ case TLS1_VERSION:
+ res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1);
+ if(res == WOLFSSL_SUCCESS)
+ return res;
+ FALLTHROUGH();
+ case TLS1_1_VERSION:
+ res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_1);
+ if(res == WOLFSSL_SUCCESS)
+ return res;
+ FALLTHROUGH();
+ case TLS1_2_VERSION:
+ res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_2);
+#ifdef WOLFSSL_TLS13
+ if(res == WOLFSSL_SUCCESS)
+ return res;
+ FALLTHROUGH();
+ case TLS1_3_VERSION:
+ res = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_3);
+#endif
+ }
+ return res;
+}
+static int
+wssl_legacy_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version)
+{
+ (void) ctx, (void) version;
+ return WOLFSSL_NOT_IMPLEMENTED;
+}
+#define wolfSSL_CTX_set_min_proto_version wssl_legacy_CTX_set_min_proto_version
+#define wolfSSL_CTX_set_max_proto_version wssl_legacy_CTX_set_max_proto_version
+#endif
+
/*
* This function loads all the client/CA certificates and CRLs. Setup the TLS
* layer and do all necessary magic.
static CURLcode
wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
{
+ int res;
char *ciphers, *curves;
struct ssl_connect_data *connssl = cf->ctx;
struct wolfssl_ctx *backend =
#ifdef WOLFSSL_HAVE_KYBER
word16 pqkem = 0;
size_t idx = 0;
-#endif
-#ifdef HAVE_SNI
- bool sni = FALSE;
-#define use_sni(x) sni = (x)
-#else
-#define use_sni(x) Curl_nop_stmt
#endif
DEBUGASSERT(backend);
if(connssl->state == ssl_connection_complete)
return CURLE_OK;
- if(conn_config->version_max != CURL_SSLVERSION_MAX_NONE) {
- failf(data, "wolfSSL does not support to set maximum SSL/TLS version");
- return CURLE_SSL_CONNECT_ERROR;
+#if LIBWOLFSSL_VERSION_HEX < 0x04002000 /* 4.2.0 (2019) */
+ req_method = wolfSSLv23_client_method();
+#else
+ req_method = wolfTLS_client_method();
+#endif
+ if(!req_method) {
+ failf(data, "wolfSSL: could not create a client method");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ if(backend->ctx)
+ wolfSSL_CTX_free(backend->ctx);
+
+ backend->ctx = wolfSSL_CTX_new(req_method);
+ if(!backend->ctx) {
+ failf(data, "wolfSSL: could not create a context");
+ return CURLE_OUT_OF_MEMORY;
}
- /* check to see if we have been told to use an explicit SSL/TLS version */
switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
-#if LIBWOLFSSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
- /* minimum protocol version is set later after the CTX object is created */
- req_method = SSLv23_client_method();
-#else
- infof(data, "wolfSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, "
- "TLS 1.0 is used exclusively");
- req_method = TLSv1_client_method();
-#endif
- use_sni(TRUE);
+ res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_VERSION);
break;
- case CURL_SSLVERSION_TLSv1_0:
-#if defined(WOLFSSL_ALLOW_TLSV10) && !defined(NO_OLD_TLS)
- req_method = TLSv1_client_method();
- use_sni(TRUE);
- break;
-#else
- failf(data, "wolfSSL does not support TLS 1.0");
- return CURLE_NOT_BUILT_IN;
-#endif
case CURL_SSLVERSION_TLSv1_1:
-#ifndef NO_OLD_TLS
- req_method = TLSv1_1_client_method();
- use_sni(TRUE);
+ res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_1_VERSION);
break;
-#else
- failf(data, "wolfSSL does not support TLS 1.1");
- return CURLE_NOT_BUILT_IN;
-#endif
case CURL_SSLVERSION_TLSv1_2:
-#ifndef WOLFSSL_NO_TLS12
- req_method = TLSv1_2_client_method();
- use_sni(TRUE);
-#else
- failf(data, "wolfSSL does not support TLS 1.2");
- return CURLE_NOT_BUILT_IN;
-#endif
+ res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_2_VERSION);
break;
- case CURL_SSLVERSION_TLSv1_3:
#ifdef WOLFSSL_TLS13
- req_method = wolfTLSv1_3_client_method();
- use_sni(TRUE);
+ case CURL_SSLVERSION_TLSv1_3:
+ res = wolfSSL_CTX_set_min_proto_version(backend->ctx, TLS1_3_VERSION);
break;
-#else
- failf(data, "wolfSSL: TLS 1.3 is not yet supported");
- return CURLE_SSL_CONNECT_ERROR;
#endif
default:
- failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+ failf(data, "wolfSSL: unrecognized minimum TLS version value");
return CURLE_SSL_CONNECT_ERROR;
}
-
- if(!req_method) {
- failf(data, "SSL: could not create a method");
- return CURLE_OUT_OF_MEMORY;
- }
-
- if(backend->ctx)
- wolfSSL_CTX_free(backend->ctx);
- backend->ctx = wolfSSL_CTX_new(req_method);
-
- if(!backend->ctx) {
- failf(data, "SSL: could not create a context");
- return CURLE_OUT_OF_MEMORY;
+ if(res != WOLFSSL_SUCCESS) {
+ failf(data, "wolfSSL: failed set the minimum TLS version");
+ return CURLE_SSL_CONNECT_ERROR;
}
- switch(conn_config->version) {
- case CURL_SSLVERSION_DEFAULT:
- case CURL_SSLVERSION_TLSv1:
-#if LIBWOLFSSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
- /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is
- * whatever minimum version of TLS was built in and at least TLS 1.0. For
- * later library versions that could change (eg TLS 1.0 built in but
- * defaults to TLS 1.1) so we have this short circuit evaluation to find
- * the minimum supported TLS version.
- */
- if((wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1) != 1) &&
- (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_1) != 1) &&
- (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_2) != 1)
+ switch(conn_config->version_max) {
#ifdef WOLFSSL_TLS13
- && (wolfSSL_CTX_SetMinVersion(backend->ctx, WOLFSSL_TLSV1_3) != 1)
-#endif
- ) {
- failf(data, "SSL: could not set the minimum protocol version");
- return CURLE_SSL_CONNECT_ERROR;
- }
+ case CURL_SSLVERSION_MAX_TLSv1_3:
+ res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
+ break;
#endif
- FALLTHROUGH();
- default:
+ case CURL_SSLVERSION_MAX_TLSv1_2:
+ res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_2_VERSION);
+ break;
+ case CURL_SSLVERSION_MAX_TLSv1_1:
+ res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_1_VERSION);
+ break;
+ case CURL_SSLVERSION_MAX_TLSv1_0:
+ res = wolfSSL_CTX_set_max_proto_version(backend->ctx, TLS1_VERSION);
break;
+ case CURL_SSLVERSION_MAX_DEFAULT:
+ case CURL_SSLVERSION_MAX_NONE:
+ res = WOLFSSL_SUCCESS;
+ break;
+ default:
+ failf(data, "wolfSSL: unrecognized 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;
}
#ifndef WOLFSSL_TLS13
SSL_VERIFY_NONE, NULL);
#ifdef HAVE_SNI
- if(sni && connssl->peer.sni) {
+ if(connssl->peer.sni) {
size_t sni_len = strlen(connssl->peer.sni);
if((sni_len < USHRT_MAX)) {
if(wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME,
}
#endif
}
-#if LIBWOLFSSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
else if(ASN_NO_SIGNER_E == detail) {
if(conn_config->verifypeer) {
failf(data, " CA signer not available for verification");
"continuing anyway");
}
}
-#endif
#ifdef USE_ECH
else if(-1 == detail) {
/* try access a retry_config ECHConfigList for tracing */