mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
tls: make default TLS version be minimum 1.2
This still allows users to explictily ask for 1.0 or 1.1 as the minimum version. If the TLS library allows it. Starting with this change, the CURL_SSLVERSION_DEFAULT value is no longer used as minimum version when the TLS backend are called. This also makes curl set the minimum version to 1.2 independently of libcurl for the rare case where a newer curl tool would use an older libcurl. URL: https://curl.se/mail/lib-2025-07/0007.html Assisted-by: Stefan Eissing Closes #17894
This commit is contained in:
parent
0e022d4241
commit
9d8998c994
@ -42,7 +42,7 @@ Use one of the available defines for this purpose. The available options are:
|
||||
## CURL_SSLVERSION_DEFAULT
|
||||
|
||||
The default acceptable version range. The minimum acceptable version is by
|
||||
default TLS v1.0 since 7.39.0 (unless the TLS library has a stricter rule).
|
||||
default TLS v1.2 since 8.16.0 (unless the TLS library has a stricter rule).
|
||||
|
||||
## CURL_SSLVERSION_TLSv1
|
||||
|
||||
|
||||
12
lib/setopt.c
12
lib/setopt.c
@ -327,8 +327,8 @@ static CURLcode setopt_HTTP_VERSION(struct Curl_easy *data, long arg)
|
||||
#endif /* ! CURL_DISABLE_HTTP */
|
||||
|
||||
#ifdef USE_SSL
|
||||
static CURLcode setopt_SSLVERSION(struct Curl_easy *data, CURLoption option,
|
||||
long arg)
|
||||
CURLcode Curl_setopt_SSLVERSION(struct Curl_easy *data, CURLoption option,
|
||||
long arg)
|
||||
{
|
||||
/*
|
||||
* Set explicit SSL version to try to connect with, as some SSL
|
||||
@ -353,6 +353,8 @@ static CURLcode setopt_SSLVERSION(struct Curl_easy *data, CURLoption option,
|
||||
version_max < CURL_SSLVERSION_MAX_NONE ||
|
||||
version_max >= CURL_SSLVERSION_MAX_LAST)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
if(version == CURL_SSLVERSION_DEFAULT)
|
||||
version = CURL_SSLVERSION_TLSv1_2;
|
||||
|
||||
primary->version = (unsigned char)version;
|
||||
primary->version_max = (unsigned int)version_max;
|
||||
@ -624,11 +626,7 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
case CURLOPT_PROXY_SSLVERSION:
|
||||
#endif
|
||||
#ifdef USE_SSL
|
||||
return setopt_SSLVERSION(data, option, arg);
|
||||
#else
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
return Curl_setopt_SSLVERSION(data, option, arg);
|
||||
|
||||
case CURLOPT_POSTFIELDSIZE:
|
||||
/*
|
||||
|
||||
@ -24,6 +24,13 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef USE_SSL
|
||||
CURLcode Curl_setopt_SSLVERSION(struct Curl_easy *data, CURLoption option,
|
||||
long arg);
|
||||
#else
|
||||
#define Curl_setopt_SSLVERSION(a,b,c) CURLE_NOT_BUILT_IN
|
||||
#endif
|
||||
|
||||
CURLcode Curl_setstropt(char **charp, const char *s) WARN_UNUSED_RESULT;
|
||||
CURLcode Curl_setblobopt(struct curl_blob **blobp,
|
||||
const struct curl_blob *blob) WARN_UNUSED_RESULT;
|
||||
|
||||
@ -458,6 +458,14 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* set default minimum TLS version */
|
||||
#ifdef USE_SSL
|
||||
Curl_setopt_SSLVERSION(data, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
Curl_setopt_SSLVERSION(data, CURLOPT_PROXY_SSLVERSION,
|
||||
CURL_SSLVERSION_DEFAULT);
|
||||
#endif
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
set->wildcard_enabled = FALSE;
|
||||
set->chunk_bgn = ZERO_NULL;
|
||||
|
||||
@ -334,12 +334,13 @@ gnutls_set_ssl_version_min_max(struct Curl_easy *data,
|
||||
if((ssl_version == CURL_SSLVERSION_DEFAULT) ||
|
||||
(ssl_version == CURL_SSLVERSION_TLSv1))
|
||||
ssl_version = CURL_SSLVERSION_TLSv1_0;
|
||||
if(ssl_version_max == CURL_SSLVERSION_MAX_NONE)
|
||||
ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT;
|
||||
if((ssl_version_max == CURL_SSLVERSION_MAX_NONE) ||
|
||||
(ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT))
|
||||
ssl_version_max = tls13support ?
|
||||
CURL_SSLVERSION_MAX_TLSv1_3 : CURL_SSLVERSION_MAX_TLSv1_2;
|
||||
|
||||
if(peer->transport == TRNSPRT_QUIC) {
|
||||
if((ssl_version_max != CURL_SSLVERSION_MAX_DEFAULT) &&
|
||||
(ssl_version_max < CURL_SSLVERSION_MAX_TLSv1_3)) {
|
||||
if(ssl_version_max < CURL_SSLVERSION_MAX_TLSv1_3) {
|
||||
failf(data, "QUIC needs at least TLS version 1.3");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
@ -347,19 +348,6 @@ gnutls_set_ssl_version_min_max(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(!tls13support) {
|
||||
/* If the running GnuTLS does not support TLS 1.3, we must not specify a
|
||||
prioritylist involving that since it will make GnuTLS return an en
|
||||
error back at us */
|
||||
if((ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) ||
|
||||
(ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT)) {
|
||||
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||
}
|
||||
}
|
||||
else if(ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT) {
|
||||
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3;
|
||||
}
|
||||
|
||||
switch(ssl_version | ssl_version_max) {
|
||||
case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
|
||||
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
@ -910,11 +898,6 @@ static CURLcode gtls_client_init(struct Curl_cfilter *cf,
|
||||
|
||||
#if defined(GNUTLS_NO_TICKETS_TLS12)
|
||||
init_flags |= GNUTLS_NO_TICKETS_TLS12;
|
||||
#elif defined(GNUTLS_NO_TICKETS)
|
||||
/* Disable TLS session tickets for non 1.3 connections */
|
||||
if((config->version != CURL_SSLVERSION_TLSv1_3) &&
|
||||
(config->version != CURL_SSLVERSION_DEFAULT))
|
||||
init_flags |= GNUTLS_NO_TICKETS;
|
||||
#endif
|
||||
|
||||
#if defined(GNUTLS_NO_STATUS_REQUEST)
|
||||
@ -1144,9 +1127,7 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx,
|
||||
else {
|
||||
infof(data, "SSL reusing session with ALPN '%s'",
|
||||
scs->alpn ? scs->alpn : "-");
|
||||
if(ssl_config->earlydata && scs->alpn &&
|
||||
!cf->conn->connect_only &&
|
||||
(gnutls_protocol_get_version(gctx->session) == GNUTLS_TLS1_3)) {
|
||||
if(ssl_config->earlydata && scs->alpn && !cf->conn->connect_only) {
|
||||
bool do_early_data = FALSE;
|
||||
if(sess_reuse_cb) {
|
||||
result = sess_reuse_cb(cf, data, &alpns, scs, &do_early_data);
|
||||
|
||||
@ -229,6 +229,53 @@ extern const unsigned char curl_ca_embed[];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static long tlsversion(unsigned char mintls,
|
||||
unsigned char maxtls)
|
||||
{
|
||||
long tlsver = 0;
|
||||
if(!mintls) { /* minimum is at default */
|
||||
/* minimum is set to default, which we want to be 1.2 */
|
||||
if(maxtls && (maxtls < 3))
|
||||
/* max is set lower than 1.2 and minimum is default, change minimum to
|
||||
the same as max */
|
||||
mintls = maxtls;
|
||||
}
|
||||
switch(mintls) {
|
||||
case 1:
|
||||
tlsver = CURL_SSLVERSION_TLSv1_0;
|
||||
break;
|
||||
case 2:
|
||||
tlsver = CURL_SSLVERSION_TLSv1_1;
|
||||
break;
|
||||
case 0: /* let default minimum be 1.2 */
|
||||
case 3:
|
||||
tlsver = CURL_SSLVERSION_TLSv1_2;
|
||||
break;
|
||||
case 4:
|
||||
default: /* just in case */
|
||||
tlsver = CURL_SSLVERSION_TLSv1_3;
|
||||
break;
|
||||
}
|
||||
switch(maxtls) {
|
||||
case 0: /* not set, leave it */
|
||||
break;
|
||||
case 1:
|
||||
tlsver |= CURL_SSLVERSION_MAX_TLSv1_0;
|
||||
break;
|
||||
case 2:
|
||||
tlsver |= CURL_SSLVERSION_MAX_TLSv1_1;
|
||||
break;
|
||||
case 3:
|
||||
tlsver |= CURL_SSLVERSION_MAX_TLSv1_2;
|
||||
break;
|
||||
case 4:
|
||||
default: /* just in case */
|
||||
tlsver |= CURL_SSLVERSION_MAX_TLSv1_3;
|
||||
break;
|
||||
}
|
||||
return tlsver;
|
||||
}
|
||||
|
||||
/* only called if libcurl supports TLS */
|
||||
static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl)
|
||||
{
|
||||
@ -360,7 +407,8 @@ static CURLcode ssl_setopts(struct OperationConfig *config, CURL *curl)
|
||||
my_setopt_long(curl, CURLOPT_DOH_SSL_VERIFYSTATUS, 1);
|
||||
|
||||
my_setopt_SSLVERSION(curl, CURLOPT_SSLVERSION,
|
||||
config->ssl_version | config->ssl_version_max);
|
||||
tlsversion(config->ssl_version,
|
||||
config->ssl_version_max));
|
||||
if(config->proxy)
|
||||
my_setopt_SSLVERSION(curl, CURLOPT_PROXY_SSLVERSION,
|
||||
config->proxy_ssl_version);
|
||||
|
||||
@ -196,8 +196,6 @@ struct OperationConfig {
|
||||
curl_off_t sendpersecond; /* send to peer */
|
||||
curl_off_t recvpersecond; /* receive from peer */
|
||||
|
||||
long ssl_version;
|
||||
long ssl_version_max;
|
||||
long proxy_ssl_version;
|
||||
long ip_version;
|
||||
long create_file_mode; /* CURLOPT_NEW_FILE_PERMS */
|
||||
@ -241,6 +239,8 @@ struct OperationConfig {
|
||||
} file_clobber_mode;
|
||||
unsigned char upload_flags; /* Bitmask for --upload-flags */
|
||||
unsigned short porttouse;
|
||||
unsigned char ssl_version; /* 0 - 4, 0 being default */
|
||||
unsigned char ssl_version_max; /* 0 - 4, 0 being default */
|
||||
BIT(remote_name_all); /* --remote-name-all */
|
||||
BIT(remote_time);
|
||||
BIT(cookiesession); /* new session? */
|
||||
|
||||
@ -1682,10 +1682,23 @@ static void opt_depr(struct GlobalConfig *global,
|
||||
warnf(global, "--%s is deprecated and has no function anymore", a->lname);
|
||||
}
|
||||
|
||||
static ParameterError opt_sslver(struct OperationConfig *config,
|
||||
unsigned char ver)
|
||||
{
|
||||
if(config->ssl_version_max &&
|
||||
(config->ssl_version_max < ver)) {
|
||||
errorf(config->global, "Minimum TLS version set higher than max");
|
||||
return PARAM_BAD_USE;
|
||||
}
|
||||
config->ssl_version = ver;
|
||||
return PARAM_OK;
|
||||
}
|
||||
|
||||
/* opt_none is the function that handles ARG_NONE options */
|
||||
static ParameterError opt_none(struct OperationConfig *config,
|
||||
const struct LongShort *a)
|
||||
{
|
||||
ParameterError err = PARAM_OK;
|
||||
switch(a->cmd) {
|
||||
case C_ANYAUTH: /* --anyauth */
|
||||
config->authtype = CURLAUTH_ANY;
|
||||
@ -1731,19 +1744,19 @@ static ParameterError opt_none(struct OperationConfig *config,
|
||||
sethttpver(config, CURL_HTTP_VERSION_3ONLY);
|
||||
break;
|
||||
case C_TLSV1: /* --tlsv1 */
|
||||
config->ssl_version = CURL_SSLVERSION_TLSv1;
|
||||
err = opt_sslver(config, 1);
|
||||
break;
|
||||
case C_TLSV1_0: /* --tlsv1.0 */
|
||||
config->ssl_version = CURL_SSLVERSION_TLSv1_0;
|
||||
err = opt_sslver(config, 1);
|
||||
break;
|
||||
case C_TLSV1_1: /* --tlsv1.1 */
|
||||
config->ssl_version = CURL_SSLVERSION_TLSv1_1;
|
||||
err = opt_sslver(config, 2);
|
||||
break;
|
||||
case C_TLSV1_2: /* --tlsv1.2 */
|
||||
config->ssl_version = CURL_SSLVERSION_TLSv1_2;
|
||||
err = opt_sslver(config, 3);
|
||||
break;
|
||||
case C_TLSV1_3: /* --tlsv1.3 */
|
||||
config->ssl_version = CURL_SSLVERSION_TLSv1_3;
|
||||
err = opt_sslver(config, 4);
|
||||
break;
|
||||
case C_IPV4: /* --ipv4 */
|
||||
config->ip_version = CURL_IPRESOLVE_V4;
|
||||
@ -1758,7 +1771,7 @@ static ParameterError opt_none(struct OperationConfig *config,
|
||||
config->proxy_ssl_version = CURL_SSLVERSION_TLSv1;
|
||||
break;
|
||||
}
|
||||
return PARAM_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* opt_bool is the function that handles boolean options */
|
||||
@ -2423,6 +2436,10 @@ static ParameterError opt_filestring(struct OperationConfig *config,
|
||||
break;
|
||||
case C_TLS_MAX: /* --tls-max */
|
||||
err = str2tls_max(&config->ssl_version_max, nextarg);
|
||||
if(!err && (config->ssl_version_max < config->ssl_version)) {
|
||||
errorf(global, "--tls-max set lower than minimum accepted version");
|
||||
err = PARAM_BAD_USE;
|
||||
}
|
||||
break;
|
||||
case C_HAPPY_EYEBALLS_TIMEOUT_MS: /* --happy-eyeballs-timeout-ms */
|
||||
err = str2unum(&config->happy_eyeballs_timeout_ms, nextarg);
|
||||
|
||||
@ -739,17 +739,17 @@ CURLcode get_args(struct OperationConfig *config, const size_t i)
|
||||
* data.
|
||||
*/
|
||||
|
||||
ParameterError str2tls_max(long *val, const char *str)
|
||||
ParameterError str2tls_max(unsigned char *val, const char *str)
|
||||
{
|
||||
static struct s_tls_max {
|
||||
static struct s_tls_max {
|
||||
const char *tls_max_str;
|
||||
long tls_max;
|
||||
unsigned char tls_max;
|
||||
} const tls_max_array[] = {
|
||||
{ "default", CURL_SSLVERSION_MAX_DEFAULT },
|
||||
{ "1.0", CURL_SSLVERSION_MAX_TLSv1_0 },
|
||||
{ "1.1", CURL_SSLVERSION_MAX_TLSv1_1 },
|
||||
{ "1.2", CURL_SSLVERSION_MAX_TLSv1_2 },
|
||||
{ "1.3", CURL_SSLVERSION_MAX_TLSv1_3 }
|
||||
{ "default", 0 }, /* lets the library decide */
|
||||
{ "1.0", 1 },
|
||||
{ "1.1", 2 },
|
||||
{ "1.2", 3 },
|
||||
{ "1.3", 4 }
|
||||
};
|
||||
size_t i = 0;
|
||||
if(!str)
|
||||
|
||||
@ -64,6 +64,6 @@ int ftpcccmethod(struct OperationConfig *config, const char *str);
|
||||
|
||||
long delegation(struct OperationConfig *config, const char *str);
|
||||
|
||||
ParameterError str2tls_max(long *val, const char *str);
|
||||
ParameterError str2tls_max(unsigned char *val, const char *str);
|
||||
|
||||
#endif /* HEADER_CURL_TOOL_PARAMHLP_H */
|
||||
|
||||
@ -101,7 +101,7 @@ const struct NameValue setopt_nv_CURL_SSLVERSION[] = {
|
||||
};
|
||||
|
||||
const struct NameValue setopt_nv_CURL_SSLVERSION_MAX[] = {
|
||||
NV(CURL_SSLVERSION_MAX_NONE),
|
||||
{"", CURL_SSLVERSION_MAX_NONE},
|
||||
NV(CURL_SSLVERSION_MAX_DEFAULT),
|
||||
NV(CURL_SSLVERSION_MAX_TLSv1_0),
|
||||
NV(CURL_SSLVERSION_MAX_TLSv1_1),
|
||||
@ -293,9 +293,16 @@ CURLcode tool_setopt_SSLVERSION(CURL *curl, struct OperationConfig *config,
|
||||
name, lval);
|
||||
}
|
||||
else {
|
||||
ret = easysrc_addf(&easysrc_code,
|
||||
"curl_easy_setopt(hnd, %s, (long)(%s | %s));",
|
||||
name, nv->name, nv2->name);
|
||||
if(nv2->name && *nv2->name)
|
||||
/* if max is set */
|
||||
ret = easysrc_addf(&easysrc_code,
|
||||
"curl_easy_setopt(hnd, %s, (long)(%s | %s));",
|
||||
name, nv->name, nv2->name);
|
||||
else
|
||||
/* without a max */
|
||||
ret = easysrc_addf(&easysrc_code,
|
||||
"curl_easy_setopt(hnd, %s, (long)%s);",
|
||||
name, nv->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -55,6 +55,7 @@ s/(USERAGENT, \")[^\"]+/${1}stripped/
|
||||
$_ = '' if /CURLOPT_SSL_VERIFYPEER/
|
||||
$_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
$_ = '' if /CURLOPT_HTTP09_ALLOWED/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
</stripfile>
|
||||
|
||||
@ -66,6 +66,7 @@ $_ = '' if /CURLOPT_SSL_VERIFYPEER/
|
||||
$_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
</stripfile>
|
||||
<file name="%LOGDIR/test%TESTNUMBER.c" mode="text">
|
||||
/********* Sample code generated by the curl command line tool **********
|
||||
|
||||
@ -60,6 +60,7 @@ $_ = '' if /CURLOPT_SSL_VERIFYPEER/
|
||||
$_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
</stripfile>
|
||||
<file name="%LOGDIR/test%TESTNUMBER.c" mode="text">
|
||||
/********* Sample code generated by the curl command line tool **********
|
||||
|
||||
@ -57,6 +57,7 @@ $_ = '' if /CURLOPT_SSL_VERIFYPEER/
|
||||
$_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
</stripfile>
|
||||
<file name="%LOGDIR/test%TESTNUMBER.c" mode="text">
|
||||
/********* Sample code generated by the curl command line tool **********
|
||||
|
||||
@ -99,6 +99,7 @@ $_ = '' if /CURLOPT_SSL_VERIFYPEER/
|
||||
$_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
# CURL_DOES_CONVERSION generates an extra comment.
|
||||
$_ = '' if /\/\* "value" \*\//
|
||||
</stripfile>
|
||||
|
||||
@ -145,6 +145,7 @@ $_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_HTTP09_ALLOWED/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
</stripfile>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
||||
@ -129,6 +129,7 @@ $_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_HTTP09_ALLOWED/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
</stripfile>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
||||
@ -107,6 +107,7 @@ $_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_HTTP09_ALLOWED/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
</stripfile>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
||||
@ -111,6 +111,7 @@ $_ = '' if /CURLOPT_SSL_VERIFYPEER/
|
||||
$_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
</stripfile>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
||||
@ -63,6 +63,7 @@ $_ = '' if /CURLOPT_SSL_VERIFYPEER/
|
||||
$_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
|
||||
$_ = '' if /CURLOPT_HTTP_VERSION/
|
||||
$_ = '' if /CURLOPT_INTERLEAVEDATA/
|
||||
$_ = '' if /CURLOPT_SSLVERSION/
|
||||
</stripfile>
|
||||
<file name="%LOGDIR/test%TESTNUMBER.c" mode="text">
|
||||
/********* Sample code generated by the curl command line tool **********
|
||||
|
||||
@ -80,8 +80,8 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_PROXY, "http://%HOSTIP:%HTTPPORT");
|
||||
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
|
||||
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
|
||||
curl_easy_setopt(hnd, CURLOPT_SSLVERSION, (long)(CURL_SSLVERSION_DEFAULT | CURL_SSLVERSION_MAX_TLSv1_3));
|
||||
curl_easy_setopt(hnd, CURLOPT_PROXY_SSLVERSION, (long)(CURL_SSLVERSION_TLSv1 | CURL_SSLVERSION_MAX_NONE));
|
||||
curl_easy_setopt(hnd, CURLOPT_SSLVERSION, (long)(CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_3));
|
||||
curl_easy_setopt(hnd, CURLOPT_PROXY_SSLVERSION, (long)CURL_SSLVERSION_TLSv1);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
|
||||
/* Here is a list of options the curl code used that cannot get generated
|
||||
|
||||
@ -36,6 +36,31 @@ from testenv import Env, CurlClient, LocalClient
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TLSDefs:
|
||||
TLS_VERSIONS = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
|
||||
TLS_VERSION_IDS = {
|
||||
'TLSv1': 0x301,
|
||||
'TLSv1.1': 0x302,
|
||||
'TLSv1.2': 0x303,
|
||||
'TLSv1.3': 0x304
|
||||
}
|
||||
CURL_ARG_MIN_VERSION_ID = {
|
||||
'none': 0x0,
|
||||
'tlsv1': 0x301,
|
||||
'tlsv1.0': 0x301,
|
||||
'tlsv1.1': 0x302,
|
||||
'tlsv1.2': 0x303,
|
||||
'tlsv1.3': 0x304,
|
||||
}
|
||||
CURL_ARG_MAX_VERSION_ID = {
|
||||
'none': 0x0,
|
||||
'1.0': 0x301,
|
||||
'1.1': 0x302,
|
||||
'1.2': 0x303,
|
||||
'1.3': 0x304,
|
||||
}
|
||||
|
||||
|
||||
class TestSSLUse:
|
||||
|
||||
@pytest.fixture(autouse=True, scope='class')
|
||||
@ -270,18 +295,54 @@ class TestSSLUse:
|
||||
|
||||
@staticmethod
|
||||
def gen_test_17_09_list():
|
||||
return [[tls_proto, max_ver, min_ver]
|
||||
for tls_proto in ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
|
||||
for max_ver in range(5)
|
||||
for min_ver in range(-2, 4)]
|
||||
return [
|
||||
[server_tls, min_arg, max_arg]
|
||||
for server_tls in TLSDefs.TLS_VERSIONS
|
||||
for min_arg in TLSDefs.CURL_ARG_MIN_VERSION_ID
|
||||
for max_arg in TLSDefs.CURL_ARG_MAX_VERSION_ID
|
||||
]
|
||||
|
||||
@pytest.mark.parametrize("tls_proto, max_ver, min_ver", gen_test_17_09_list())
|
||||
def test_17_09_ssl_min_max(self, env: Env, httpd, configures_httpd, tls_proto, max_ver, min_ver):
|
||||
@pytest.mark.parametrize("server_tls, min_arg, max_arg", gen_test_17_09_list())
|
||||
def test_17_09_ssl_min_max(self, env: Env, httpd, configures_httpd, server_tls, min_arg, max_arg):
|
||||
# We test if curl using min/max versions arguments (and defaults) can connect
|
||||
# to a server using 'server_tls' version only
|
||||
httpd.set_extra_config('base', [
|
||||
f'SSLProtocol {tls_proto}',
|
||||
f'SSLProtocol {server_tls}',
|
||||
'SSLCipherSuite ALL:@SECLEVEL=0',
|
||||
])
|
||||
httpd.reload_if_config_changed()
|
||||
# curl's TLS backend supported version
|
||||
if env.curl_uses_lib('gnutls') or \
|
||||
env.curl_uses_lib('quiche') or \
|
||||
env.curl_uses_lib('aws-lc'):
|
||||
curl_supported = [0x301, 0x302, 0x303, 0x304]
|
||||
elif env.curl_uses_lib('openssl') and \
|
||||
env.curl_lib_version_before('openssl', '3.0.0'):
|
||||
curl_supported = [0x301, 0x302, 0x303, 0x304]
|
||||
else: # most SSL backends dropped support for TLSv1.0, TLSv1.1
|
||||
curl_supported = [0x303, 0x304]
|
||||
|
||||
extra_args = ['--trace-config', 'ssl']
|
||||
|
||||
# determine effective min/max version used by curl with these args
|
||||
if max_arg != 'none':
|
||||
extra_args.extend(['--tls-max', max_arg])
|
||||
curl_max_ver = TLSDefs.CURL_ARG_MAX_VERSION_ID[max_arg]
|
||||
else:
|
||||
curl_max_ver = max(TLSDefs.TLS_VERSION_IDS.values())
|
||||
if min_arg != 'none':
|
||||
extra_args.append(f'--{min_arg}')
|
||||
curl_min_ver = TLSDefs.CURL_ARG_MIN_VERSION_ID[min_arg]
|
||||
else:
|
||||
curl_min_ver = min(0x303, curl_max_ver) # TLSv1.2 is the default now
|
||||
|
||||
# collect all versions that curl is allowed with this command lines and supports
|
||||
curl_allowed = [tid for tid in sorted(TLSDefs.TLS_VERSION_IDS.values())
|
||||
if curl_min_ver <= tid <= curl_max_ver and
|
||||
tid in curl_supported]
|
||||
# we expect a successful transfer, when the server TLS version is allowed
|
||||
server_ver = TLSDefs.TLS_VERSION_IDS[server_tls]
|
||||
# do the transfer
|
||||
proto = 'http/1.1'
|
||||
run_env = os.environ.copy()
|
||||
if env.curl_uses_lib('gnutls'):
|
||||
@ -295,29 +356,14 @@ class TestSSLUse:
|
||||
run_env['GNUTLS_SYSTEM_PRIORITY_FILE'] = our_config
|
||||
curl = CurlClient(env=env, run_env=run_env)
|
||||
url = f'https://{env.authority_for(env.domain1, proto)}/curltest/sslinfo'
|
||||
# SSL backend specifics
|
||||
if env.curl_uses_lib('gnutls'):
|
||||
supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
|
||||
elif env.curl_uses_lib('quiche'):
|
||||
supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
|
||||
elif env.curl_uses_lib('aws-lc'):
|
||||
supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
|
||||
elif env.curl_uses_lib('openssl') and \
|
||||
env.curl_lib_version_before('openssl', '3.0.0'):
|
||||
supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']
|
||||
else: # most SSL backends dropped support for TLSv1.0, TLSv1.1
|
||||
supported = [None, None, 'TLSv1.2', 'TLSv1.3']
|
||||
# test
|
||||
extra_args = [[], ['--tlsv1'], ['--tlsv1.0'], ['--tlsv1.1'], ['--tlsv1.2'], ['--tlsv1.3']][min_ver+2] + \
|
||||
[['--tls-max', '1.0'], ['--tls-max', '1.1'], ['--tls-max', '1.2'], ['--tls-max', '1.3'], []][max_ver]
|
||||
extra_args.extend(['--trace-config', 'ssl'])
|
||||
r = curl.http_get(url=url, alpn_proto=proto, extra_args=extra_args)
|
||||
if max_ver >= min_ver and tls_proto in supported[max(0, min_ver):min(max_ver, 3)+1]:
|
||||
assert r.exit_code == 0, f'extra_args={extra_args}\n{r.dump_logs()}'
|
||||
|
||||
if server_ver in curl_allowed:
|
||||
assert r.exit_code == 0, f'should succeed, server={server_ver:04x}, curl=[{curl_min_ver:04x}, {curl_max_ver:04x}], allowed={curl_allowed}\n{r.dump_logs()}'
|
||||
assert r.json['HTTPS'] == 'on', r.dump_logs()
|
||||
assert r.json['SSL_PROTOCOL'] == tls_proto, r.dump_logs()
|
||||
assert r.json['SSL_PROTOCOL'] == server_tls, r.dump_logs()
|
||||
else:
|
||||
assert r.exit_code != 0, f'extra_args={extra_args}\n{r.dump_logs()}'
|
||||
assert r.exit_code != 0, f'should fail, server={server_ver:04x}, curl=[{curl_min_ver:04x}, {curl_max_ver:04x}]\n{r.dump_logs()}'
|
||||
|
||||
def test_17_10_h3_session_reuse(self, env: Env, httpd, nghttpx):
|
||||
if not env.have_h3():
|
||||
|
||||
Loading…
Reference in New Issue
Block a user