mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
vtls: add options to specify range of enabled TLS versions
This commit introduces the CURL_SSLVERSION_MAX_* constants as well as the --tls-max option of the curl tool. Closes https://github.com/curl/curl/pull/1166
This commit is contained in:
parent
b666907336
commit
6448f98c18
24
docs/cmdline-opts/tls-max.d
Normal file
24
docs/cmdline-opts/tls-max.d
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
Long: tls-max
|
||||||
|
Arg: <VERSION>
|
||||||
|
Tags: Versions
|
||||||
|
Protocols: SSL
|
||||||
|
Added: 7.54.0
|
||||||
|
Requires: TLS
|
||||||
|
See-also: tlsv1.0 tlsv1.1 tlsv1.2
|
||||||
|
Help: Use TLSv1.0 or greater
|
||||||
|
---
|
||||||
|
VERSION defines maximum supported TLS version. A minimum is defined
|
||||||
|
by arguments tlsv1.0 or tlsv1.1 or tlsv1.2.
|
||||||
|
|
||||||
|
.RS
|
||||||
|
.IP "default"
|
||||||
|
Use up to recommended TLS version.
|
||||||
|
.IP "1.0"
|
||||||
|
Use up to TLSv1.0.
|
||||||
|
.IP "1.1"
|
||||||
|
Use up to TLSv1.1.
|
||||||
|
.IP "1.2"
|
||||||
|
Use up to TLSv1.2.
|
||||||
|
.IP "1.3"
|
||||||
|
Use up to TLSv1.3.
|
||||||
|
.RE
|
@ -46,6 +46,23 @@ TLSv1.1
|
|||||||
TLSv1.2
|
TLSv1.2
|
||||||
.IP CURL_SSLVERSION_TLSv1_3
|
.IP CURL_SSLVERSION_TLSv1_3
|
||||||
TLSv1.3
|
TLSv1.3
|
||||||
|
.IP CURL_SSLVERSION_MAX_DEFAULT
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.2 or default
|
||||||
|
value from SSL library. Only library NSS currently allows to get
|
||||||
|
maximum supported TLS version.
|
||||||
|
(Added in 7.54.0)
|
||||||
|
.IP CURL_SSLVERSION_MAX_TLSv1_0
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.0.
|
||||||
|
(Added in 7.54.0)
|
||||||
|
.IP CURL_SSLVERSION_MAX_TLSv1_1
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.1.
|
||||||
|
(Added in 7.54.0)
|
||||||
|
.IP CURL_SSLVERSION_MAX_TLSv1_2
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.2.
|
||||||
|
(Added in 7.54.0)
|
||||||
|
.IP CURL_SSLVERSION_MAX_TLSv1_3
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.3.
|
||||||
|
(Added in 7.54.0)
|
||||||
.RE
|
.RE
|
||||||
.SH DEFAULT
|
.SH DEFAULT
|
||||||
CURL_SSLVERSION_DEFAULT
|
CURL_SSLVERSION_DEFAULT
|
||||||
@ -58,7 +75,8 @@ if(curl) {
|
|||||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||||
|
|
||||||
/* ask libcurl to use TLS version 1.0 or later */
|
/* ask libcurl to use TLS version 1.0 or later */
|
||||||
curl_easy_setopt(curl, CURLOPT_PROXY_SSLVERSION, CURL_SSLVERSION_TLSv1);
|
curl_easy_setopt(curl, CURLOPT_PROXY_SSLVERSION, CURL_SSLVERSION_TLSv1_1 |
|
||||||
|
CURL_SSLVERSION_MAX_DEFAULT);
|
||||||
|
|
||||||
/* Perform the request */
|
/* Perform the request */
|
||||||
curl_easy_perform(curl);
|
curl_easy_perform(curl);
|
||||||
|
@ -50,6 +50,23 @@ TLSv1.1 (Added in 7.34.0)
|
|||||||
TLSv1.2 (Added in 7.34.0)
|
TLSv1.2 (Added in 7.34.0)
|
||||||
.IP CURL_SSLVERSION_TLSv1_3
|
.IP CURL_SSLVERSION_TLSv1_3
|
||||||
TLSv1.3 (Added in 7.52.0)
|
TLSv1.3 (Added in 7.52.0)
|
||||||
|
.IP CURL_SSLVERSION_MAX_DEFAULT
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.2 or default
|
||||||
|
value from SSL library. Only library NSS currently allows to get
|
||||||
|
maximum supported TLS version.
|
||||||
|
(Added in 7.54.0)
|
||||||
|
.IP CURL_SSLVERSION_MAX_TLSv1_0
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.0.
|
||||||
|
(Added in 7.54.0)
|
||||||
|
.IP CURL_SSLVERSION_MAX_TLSv1_1
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.1.
|
||||||
|
(Added in 7.54.0)
|
||||||
|
.IP CURL_SSLVERSION_MAX_TLSv1_2
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.2.
|
||||||
|
(Added in 7.54.0)
|
||||||
|
.IP CURL_SSLVERSION_MAX_TLSv1_3
|
||||||
|
The flag defines maximum supported TLS version as TLSv1.3.
|
||||||
|
(Added in 7.54.0)
|
||||||
.RE
|
.RE
|
||||||
.SH DEFAULT
|
.SH DEFAULT
|
||||||
CURL_SSLVERSION_DEFAULT
|
CURL_SSLVERSION_DEFAULT
|
||||||
@ -61,8 +78,9 @@ CURL *curl = curl_easy_init();
|
|||||||
if(curl) {
|
if(curl) {
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||||
|
|
||||||
/* ask libcurl to use TLS version 1.0 or later */
|
/* ask libcurl to use TLS version 1.1 or later */
|
||||||
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
|
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1.1 |
|
||||||
|
CURL_SSLVERSION_MAX_DEFAULT);
|
||||||
|
|
||||||
/* Perform the request */
|
/* Perform the request */
|
||||||
curl_easy_perform(curl);
|
curl_easy_perform(curl);
|
||||||
|
@ -798,6 +798,12 @@ CURL_SSLVERSION_TLSv1_0 7.34.0
|
|||||||
CURL_SSLVERSION_TLSv1_1 7.34.0
|
CURL_SSLVERSION_TLSv1_1 7.34.0
|
||||||
CURL_SSLVERSION_TLSv1_2 7.34.0
|
CURL_SSLVERSION_TLSv1_2 7.34.0
|
||||||
CURL_SSLVERSION_TLSv1_3 7.52.0
|
CURL_SSLVERSION_TLSv1_3 7.52.0
|
||||||
|
CURL_SSLVERSION_MAX_NONE 7.54.0
|
||||||
|
CURL_SSLVERSION_MAX_DEFAULT 7.54.0
|
||||||
|
CURL_SSLVERSION_MAX_TLSv1_0 7.54.0
|
||||||
|
CURL_SSLVERSION_MAX_TLSv1_1 7.54.0
|
||||||
|
CURL_SSLVERSION_MAX_TLSv1_2 7.54.0
|
||||||
|
CURL_SSLVERSION_MAX_TLSv1_3 7.54.0
|
||||||
CURL_TIMECOND_IFMODSINCE 7.9.7
|
CURL_TIMECOND_IFMODSINCE 7.9.7
|
||||||
CURL_TIMECOND_IFUNMODSINCE 7.9.7
|
CURL_TIMECOND_IFUNMODSINCE 7.9.7
|
||||||
CURL_TIMECOND_LASTMOD 7.9.7
|
CURL_TIMECOND_LASTMOD 7.9.7
|
||||||
|
@ -1884,6 +1884,18 @@ enum {
|
|||||||
CURL_SSLVERSION_LAST /* never use, keep last */
|
CURL_SSLVERSION_LAST /* never use, keep last */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CURL_SSLVERSION_MAX_NONE = 0,
|
||||||
|
CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16),
|
||||||
|
CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16),
|
||||||
|
CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16),
|
||||||
|
CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16),
|
||||||
|
CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16),
|
||||||
|
|
||||||
|
/* never use, keep last */
|
||||||
|
CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16)
|
||||||
|
};
|
||||||
|
|
||||||
enum CURL_TLSAUTH {
|
enum CURL_TLSAUTH {
|
||||||
CURL_TLSAUTH_NONE,
|
CURL_TLSAUTH_NONE,
|
||||||
CURL_TLSAUTH_SRP,
|
CURL_TLSAUTH_SRP,
|
||||||
|
11
lib/url.c
11
lib/url.c
@ -695,6 +695,9 @@ CURLcode Curl_open(struct Curl_easy **curl)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define C_SSLVERSION_VALUE(x) (x & 0xffff)
|
||||||
|
#define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
|
||||||
|
|
||||||
CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
|
CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
|
||||||
va_list param)
|
va_list param)
|
||||||
{
|
{
|
||||||
@ -927,7 +930,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
|
|||||||
* implementations are lame.
|
* implementations are lame.
|
||||||
*/
|
*/
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
data->set.ssl.primary.version = va_arg(param, long);
|
arg = va_arg(param, long);
|
||||||
|
data->set.ssl.primary.version = C_SSLVERSION_VALUE(arg);
|
||||||
|
data->set.ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
|
||||||
#else
|
#else
|
||||||
result = CURLE_UNKNOWN_OPTION;
|
result = CURLE_UNKNOWN_OPTION;
|
||||||
#endif
|
#endif
|
||||||
@ -938,7 +943,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
|
|||||||
* implementations are lame.
|
* implementations are lame.
|
||||||
*/
|
*/
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
data->set.proxy_ssl.primary.version = va_arg(param, long);
|
arg = va_arg(param, long);
|
||||||
|
data->set.proxy_ssl.primary.version = C_SSLVERSION_VALUE(arg);
|
||||||
|
data->set.proxy_ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
|
||||||
#else
|
#else
|
||||||
result = CURLE_UNKNOWN_OPTION;
|
result = CURLE_UNKNOWN_OPTION;
|
||||||
#endif
|
#endif
|
||||||
|
@ -350,6 +350,7 @@ struct ssl_connect_data {
|
|||||||
|
|
||||||
struct ssl_primary_config {
|
struct ssl_primary_config {
|
||||||
long version; /* what version the client wants to use */
|
long version; /* what version the client wants to use */
|
||||||
|
long version_max; /* max supported version the client wants to use*/
|
||||||
bool verifypeer; /* set TRUE if this is desired */
|
bool verifypeer; /* set TRUE if this is desired */
|
||||||
bool verifyhost; /* set TRUE if CN/SAN must match hostname */
|
bool verifyhost; /* set TRUE if CN/SAN must match hostname */
|
||||||
bool verifystatus; /* set TRUE if certificate status must be checked */
|
bool verifystatus; /* set TRUE if certificate status must be checked */
|
||||||
|
@ -156,6 +156,12 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
|||||||
same connection */
|
same connection */
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
|
if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
|
||||||
|
failf(data, "axtls does not support CURL_SSLVERSION_MAX");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* axTLS only supports TLSv1 */
|
/* axTLS only supports TLSv1 */
|
||||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||||
switch(SSL_CONN_CONFIG(version)) {
|
switch(SSL_CONN_CONFIG(version)) {
|
||||||
|
@ -149,6 +149,11 @@ cyassl_connect_step1(struct connectdata *conn,
|
|||||||
if(conssl->state == ssl_connection_complete)
|
if(conssl->state == ssl_connection_complete)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
|
if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
|
||||||
|
failf(data, "CyaSSL does not support to set maximum SSL/TLS version");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||||
switch(SSL_CONN_CONFIG(version)) {
|
switch(SSL_CONN_CONFIG(version)) {
|
||||||
case CURL_SSLVERSION_DEFAULT:
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
|
@ -1044,6 +1044,109 @@ CF_INLINE bool is_file(const char *filename)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||||
|
static CURLcode darwinssl_version_from_curl(long *darwinver, long version)
|
||||||
|
{
|
||||||
|
switch(ssl_version) {
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
*darwinver = kTLSProtocol1;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
*darwinver = kTLSProtocol11;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
*darwinver = kTLSProtocol12;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
set_ssl_version_min_max(struct connectdata *conn, int sockindex)
|
||||||
|
{
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
long ssl_version = SSL_CONN_CONFIG(version);
|
||||||
|
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||||
|
|
||||||
|
switch(ssl_version) {
|
||||||
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
ssl_version = CURL_SSLVERSION_TLSv1_0;
|
||||||
|
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(ssl_version_max) {
|
||||||
|
case CURL_SSLVERSION_MAX_NONE:
|
||||||
|
ssl_version_max = ssl_version << 16;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||||
|
if(SSLSetProtocolVersionMax != NULL) {
|
||||||
|
SSLProtocol darwin_ver_min = kTLSProtocol1;
|
||||||
|
SSLProtocol darwin_ver_max = kTLSProtocol1;
|
||||||
|
CURLcode result = darwinssl_version_from_curl(&darwin_ver_min,
|
||||||
|
ssl_version);
|
||||||
|
if(result) {
|
||||||
|
failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = darwinssl_version_from_curl(&darwin_ver_max,
|
||||||
|
ssl_version_max >> 16);
|
||||||
|
if(result) {
|
||||||
|
failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, darwin_ver_min);
|
||||||
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, darwin_ver_max);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if CURL_SUPPORT_MAC_10_8
|
||||||
|
long i = ssl_version;
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kSSLProtocolAll,
|
||||||
|
false);
|
||||||
|
for(; i <= (ssl_version_max >> 16); i++) {
|
||||||
|
switch(i) {
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kTLSProtocol1,
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kTLSProtocol11,
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kTLSProtocol12,
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
|
failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CURLE_OK;
|
||||||
|
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||||
|
}
|
||||||
|
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
|
||||||
|
failf(data, "DarwinSSL: cannot set SSL protocol");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||||
int sockindex)
|
int sockindex)
|
||||||
{
|
{
|
||||||
@ -1113,20 +1216,15 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
|
||||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
|
|
||||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
|
|
||||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
|
{
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
CURLcode result = set_ssl_version_min_max(conn, sockindex);
|
||||||
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
||||||
if(err != noErr) {
|
if(err != noErr) {
|
||||||
@ -1167,23 +1265,15 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
true);
|
true);
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
|
||||||
kTLSProtocol1,
|
|
||||||
true);
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
|
||||||
kTLSProtocol11,
|
|
||||||
true);
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
|
||||||
kTLSProtocol12,
|
|
||||||
true);
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
|
{
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
CURLcode result = set_ssl_version_min_max(conn, sockindex);
|
||||||
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kSSLProtocol3,
|
kSSLProtocol3,
|
||||||
@ -1209,6 +1299,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
#endif /* CURL_SUPPORT_MAC_10_8 */
|
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
|
||||||
|
failf(data, "Your version of the OS does not support to set maximum"
|
||||||
|
" SSL/TLS version");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
||||||
switch(conn->ssl_config.version) {
|
switch(conn->ssl_config.version) {
|
||||||
case CURL_SSLVERSION_DEFAULT:
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
|
@ -748,6 +748,40 @@ static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
|
|||||||
return (ssize_t) nread;
|
return (ssize_t) nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn)
|
||||||
|
{
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
long ssl_version = SSL_CONN_CONFIG(version);
|
||||||
|
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||||
|
long i = ssl_version;
|
||||||
|
switch(ssl_version_max) {
|
||||||
|
case CURL_SSLVERSION_MAX_NONE:
|
||||||
|
ssl_version_max = ssl_version;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
ssl_version_max = CURL_SSLVERSION_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(; i <= (ssl_version_max >> 16); ++i) {
|
||||||
|
switch(i) {
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
*protoflags |= CURL_GSKPROTO_TLSV10_MASK;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
*protoflags |= CURL_GSKPROTO_TLSV11_MASK;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
*protoflags |= CURL_GSKPROTO_TLSV11_MASK;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
|
failf(data, "GSKit: TLS 1.3 is not yet supported");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
@ -764,7 +798,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
|||||||
const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
|
const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
|
||||||
conn->host.name;
|
conn->host.name;
|
||||||
const char *sni;
|
const char *sni;
|
||||||
unsigned int protoflags;
|
unsigned int protoflags = 0;
|
||||||
long timeout;
|
long timeout;
|
||||||
Qso_OverlappedIO_t commarea;
|
Qso_OverlappedIO_t commarea;
|
||||||
int sockpair[2];
|
int sockpair[2];
|
||||||
@ -849,17 +883,13 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
|||||||
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
|
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
protoflags = CURL_GSKPROTO_TLSV10_MASK;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
protoflags = CURL_GSKPROTO_TLSV11_MASK;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
protoflags = CURL_GSKPROTO_TLSV12_MASK;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
failf(data, "GSKit: TLS 1.3 is not yet supported");
|
result = set_ssl_version_min_max(&protoflags, conn);
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
135
lib/vtls/gtls.c
135
lib/vtls/gtls.c
@ -375,6 +375,100 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
|
||||||
|
static CURLcode
|
||||||
|
set_ssl_version_min_max(int *list, size_t list_size, struct connectdata *conn)
|
||||||
|
{
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
long ssl_version = SSL_CONN_CONFIG(version);
|
||||||
|
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||||
|
long i = ssl_version;
|
||||||
|
long protocol_priority_idx = 0;
|
||||||
|
|
||||||
|
switch(ssl_version_max) {
|
||||||
|
case CURL_SSLVERSION_MAX_NONE:
|
||||||
|
ssl_version_max = ssl_version << 16;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; i <= (ssl_version_max >> 16) &&
|
||||||
|
protocol_priority_idx < list_size; ++i) {
|
||||||
|
switch(i) {
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_0;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_1;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_2;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
|
failf(data, "GnuTLS: TLS 1.3 is not yet supported");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
|
||||||
|
/* If GnuTLS was compiled without support for SRP it will error out if SRP is
|
||||||
|
requested in the priority string, so treat it specially
|
||||||
|
*/
|
||||||
|
#define GNUTLS_SRP "+SRP"
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
set_ssl_version_min_max(const char **prioritylist, struct connectdata *conn)
|
||||||
|
{
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
long ssl_version = SSL_CONN_CONFIG(version);
|
||||||
|
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||||
|
if(ssl_version == CURL_SSLVERSION_TLSv1_3 ||
|
||||||
|
ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) {
|
||||||
|
failf(data, "GnuTLS: TLS 1.3 is not yet supported");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
|
||||||
|
ssl_version_max = ssl_version << 16;
|
||||||
|
}
|
||||||
|
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:"
|
||||||
|
"+VERS-TLS1.0:" GNUTLS_SRP;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1:
|
||||||
|
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||||
|
"+VERS-TLS1.0:+VERS-TLS1.1:" GNUTLS_SRP;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2:
|
||||||
|
case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||||
|
"+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1:
|
||||||
|
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||||
|
"+VERS-TLS1.1:" GNUTLS_SRP;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2:
|
||||||
|
case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||||
|
"+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2:
|
||||||
|
case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||||
|
"+VERS-TLS1.2:" GNUTLS_SRP;
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
failf(data, "GnuTLS: cannot set ssl protocol");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
gtls_connect_step1(struct connectdata *conn,
|
gtls_connect_step1(struct connectdata *conn,
|
||||||
int sockindex)
|
int sockindex)
|
||||||
@ -406,13 +500,8 @@ gtls_connect_step1(struct connectdata *conn,
|
|||||||
GNUTLS_CIPHER_3DES_CBC,
|
GNUTLS_CIPHER_3DES_CBC,
|
||||||
};
|
};
|
||||||
static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
|
static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
|
||||||
static int protocol_priority[] = { 0, 0, 0, 0 };
|
int protocol_priority[] = { 0, 0, 0, 0 };
|
||||||
#else
|
#else
|
||||||
#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
|
|
||||||
/* If GnuTLS was compiled without support for SRP it will error out if SRP is
|
|
||||||
requested in the priority string, so treat it specially
|
|
||||||
*/
|
|
||||||
#define GNUTLS_SRP "+SRP"
|
|
||||||
const char *prioritylist;
|
const char *prioritylist;
|
||||||
const char *err = NULL;
|
const char *err = NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -576,7 +665,7 @@ gtls_connect_step1(struct connectdata *conn,
|
|||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(SSL_CONN_CONFIG(version) {
|
switch(SSL_CONN_CONFIG(version)) {
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
protocol_priority[0] = GNUTLS_SSL3;
|
protocol_priority[0] = GNUTLS_SSL3;
|
||||||
break;
|
break;
|
||||||
@ -587,17 +676,16 @@ gtls_connect_step1(struct connectdata *conn,
|
|||||||
protocol_priority[2] = GNUTLS_TLS1_2;
|
protocol_priority[2] = GNUTLS_TLS1_2;
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
protocol_priority[0] = GNUTLS_TLS1_0;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
protocol_priority[0] = GNUTLS_TLS1_1;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
protocol_priority[0] = GNUTLS_TLS1_2;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
failf(data, "GnuTLS: TLS 1.3 is not yet supported");
|
{
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
CURLcode result = set_ssl_version_min_max(protocol_priority,
|
||||||
|
sizeof(protocol_priority)/sizeof(protocol_priority[0]), conn);
|
||||||
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CURL_SSLVERSION_SSLv2:
|
case CURL_SSLVERSION_SSLv2:
|
||||||
failf(data, "GnuTLS does not support SSLv2");
|
failf(data, "GnuTLS does not support SSLv2");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
@ -625,20 +713,15 @@ gtls_connect_step1(struct connectdata *conn,
|
|||||||
prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP;
|
prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP;
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
|
||||||
"+VERS-TLS1.0:" GNUTLS_SRP;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
|
||||||
"+VERS-TLS1.1:" GNUTLS_SRP;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
|
||||||
"+VERS-TLS1.2:" GNUTLS_SRP;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
failf(data, "GnuTLS: TLS 1.3 is not yet supported");
|
{
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
CURLcode result = set_ssl_version_min_max(&prioritylist, conn);
|
||||||
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CURL_SSLVERSION_SSLv2:
|
case CURL_SSLVERSION_SSLv2:
|
||||||
failf(data, "GnuTLS does not support SSLv2");
|
failf(data, "GnuTLS does not support SSLv2");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
@ -157,6 +157,71 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
|
|||||||
static Curl_recv mbed_recv;
|
static Curl_recv mbed_recv;
|
||||||
static Curl_send mbed_send;
|
static Curl_send mbed_send;
|
||||||
|
|
||||||
|
static CURLcode mbedtls_version_from_curl(int *mbedver, long version)
|
||||||
|
{
|
||||||
|
switch(ssl_version) {
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
*mbedver = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
*mbedver = MBEDTLS_SSL_MINOR_VERSION_2;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
*mbedver = MBEDTLS_SSL_MINOR_VERSION_3;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
set_ssl_version_min_max(struct connectdata *conn, int sockindex)
|
||||||
|
{
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||||
|
int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||||
|
long ssl_version = SSL_CONN_CONFIG(version);
|
||||||
|
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
|
switch(ssl_version) {
|
||||||
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
ssl_version = CURL_SSLVERSION_TLSv1_0;
|
||||||
|
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(ssl_version_max) {
|
||||||
|
case CURL_SSLVERSION_MAX_NONE:
|
||||||
|
ssl_version_max = ssl_version << 16;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = mbedtls_version_from_curl(&mbedtls_ver_min, ssl_version);
|
||||||
|
if(result) {
|
||||||
|
failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = mbedtls_version_from_curl(&mbedtls_ver_max, ssl_version_max >> 16);
|
||||||
|
if(result) {
|
||||||
|
failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||||
|
mbedtls_ver_min);
|
||||||
|
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||||
|
mbedtls_ver_max);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
mbed_connect_step1(struct connectdata *conn,
|
mbed_connect_step1(struct connectdata *conn,
|
||||||
int sockindex)
|
int sockindex)
|
||||||
@ -333,29 +398,15 @@ mbed_connect_step1(struct connectdata *conn,
|
|||||||
infof(data, "mbedTLS: Set SSL version to SSLv3\n");
|
infof(data, "mbedTLS: Set SSL version to SSLv3\n");
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
|
||||||
MBEDTLS_SSL_MINOR_VERSION_1);
|
|
||||||
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
|
||||||
MBEDTLS_SSL_MINOR_VERSION_1);
|
|
||||||
infof(data, "mbedTLS: Set SSL version to TLS 1.0\n");
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
|
||||||
MBEDTLS_SSL_MINOR_VERSION_2);
|
|
||||||
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
|
||||||
MBEDTLS_SSL_MINOR_VERSION_2);
|
|
||||||
infof(data, "mbedTLS: Set SSL version to TLS 1.1\n");
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
|
||||||
MBEDTLS_SSL_MINOR_VERSION_3);
|
|
||||||
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
|
||||||
MBEDTLS_SSL_MINOR_VERSION_3);
|
|
||||||
infof(data, "mbedTLS: Set SSL version to TLS 1.2\n");
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
failf(data, "mbedTLS: TLS 1.3 is not yet supported");
|
{
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
CURLcode result = set_ssl_version_min_max(conn, sockindex);
|
||||||
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
150
lib/vtls/nss.c
150
lib/vtls/nss.c
@ -1512,78 +1512,108 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version)
|
||||||
|
{
|
||||||
|
switch(version) {
|
||||||
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
/* TODO: set sslver->max to SSL_LIBRARY_VERSION_TLS_1_3 once stable */
|
||||||
|
#ifdef SSL_LIBRARY_VERSION_TLS_1_2
|
||||||
|
*nssver = SSL_LIBRARY_VERSION_TLS_1_2;
|
||||||
|
#elif defined SSL_LIBRARY_VERSION_TLS_1_1
|
||||||
|
*nssver = SSL_LIBRARY_VERSION_TLS_1_1;
|
||||||
|
#else
|
||||||
|
*nssver = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||||
|
#endif
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_SSLv2:
|
||||||
|
*nssver = SSL_LIBRARY_VERSION_2;
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_SSLv3:
|
||||||
|
*nssver = SSL_LIBRARY_VERSION_3_0;
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
*nssver = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
#ifdef SSL_LIBRARY_VERSION_TLS_1_1
|
||||||
|
*nssver = SSL_LIBRARY_VERSION_TLS_1_1;
|
||||||
|
return CURLE_OK;
|
||||||
|
#else
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
#ifdef SSL_LIBRARY_VERSION_TLS_1_2
|
||||||
|
*nssver = SSL_LIBRARY_VERSION_TLS_1_2;
|
||||||
|
return CURLE_OK;
|
||||||
|
#else
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
|
#ifdef SSL_LIBRARY_VERSION_TLS_1_3
|
||||||
|
*nssver = SSL_LIBRARY_VERSION_TLS_1_3;
|
||||||
|
return CURLE_OK;
|
||||||
|
#else
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode nss_init_sslver(SSLVersionRange *sslver,
|
static CURLcode nss_init_sslver(SSLVersionRange *sslver,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct connectdata *conn)
|
struct connectdata *conn)
|
||||||
{
|
{
|
||||||
switch(SSL_CONN_CONFIG(version)) {
|
CURLcode result;
|
||||||
case CURL_SSLVERSION_DEFAULT:
|
const long min = SSL_CONN_CONFIG(version);
|
||||||
|
const long max = SSL_CONN_CONFIG(version_max);
|
||||||
|
|
||||||
|
/* map CURL_SSLVERSION_DEFAULT to NSS default */
|
||||||
|
if(min == CURL_SSLVERSION_DEFAULT || max == CURL_SSLVERSION_MAX_DEFAULT) {
|
||||||
/* map CURL_SSLVERSION_DEFAULT to NSS default */
|
/* map CURL_SSLVERSION_DEFAULT to NSS default */
|
||||||
if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess)
|
if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess)
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
/* ... but make sure we use at least TLSv1.0 according to libcurl API */
|
/* ... but make sure we use at least TLSv1.0 according to libcurl API */
|
||||||
if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0)
|
if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0)
|
||||||
sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
|
sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_TLSv1:
|
|
||||||
sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
|
|
||||||
/* TODO: set sslver->max to SSL_LIBRARY_VERSION_TLS_1_3 once stable */
|
|
||||||
#ifdef SSL_LIBRARY_VERSION_TLS_1_2
|
|
||||||
sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
|
|
||||||
#elif defined SSL_LIBRARY_VERSION_TLS_1_1
|
|
||||||
sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
|
|
||||||
#else
|
|
||||||
sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
|
|
||||||
#endif
|
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_SSLv2:
|
|
||||||
sslver->min = SSL_LIBRARY_VERSION_2;
|
|
||||||
sslver->max = SSL_LIBRARY_VERSION_2;
|
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_SSLv3:
|
|
||||||
sslver->min = SSL_LIBRARY_VERSION_3_0;
|
|
||||||
sslver->max = SSL_LIBRARY_VERSION_3_0;
|
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
|
||||||
sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
|
|
||||||
sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
|
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
|
||||||
#ifdef SSL_LIBRARY_VERSION_TLS_1_1
|
|
||||||
sslver->min = SSL_LIBRARY_VERSION_TLS_1_1;
|
|
||||||
sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
|
|
||||||
return CURLE_OK;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
|
||||||
#ifdef SSL_LIBRARY_VERSION_TLS_1_2
|
|
||||||
sslver->min = SSL_LIBRARY_VERSION_TLS_1_2;
|
|
||||||
sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
|
|
||||||
return CURLE_OK;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
|
||||||
#ifdef SSL_LIBRARY_VERSION_TLS_1_3
|
|
||||||
sslver->min = SSL_LIBRARY_VERSION_TLS_1_3;
|
|
||||||
sslver->max = SSL_LIBRARY_VERSION_TLS_1_3;
|
|
||||||
return CURLE_OK;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
failf(data, "TLS minor version cannot be set");
|
switch(min) {
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = nss_sslver_from_curl(&sslver->min, min);
|
||||||
|
if(result) {
|
||||||
|
failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if(max == CURL_SSLVERSION_MAX_NONE)
|
||||||
|
sslver->max = sslver->min;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(max) {
|
||||||
|
case CURL_SSLVERSION_MAX_NONE:
|
||||||
|
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = nss_sslver_from_curl(&sslver->max, max >> 16);
|
||||||
|
if(result) {
|
||||||
|
failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
|
static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
|
||||||
|
@ -1692,6 +1692,71 @@ get_ssl_version_txt(SSL *ssl)
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
set_ssl_version_min_max(long *ctx_options, struct connectdata *conn)
|
||||||
|
{
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
long ssl_version = SSL_CONN_CONFIG(version);
|
||||||
|
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||||
|
if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
|
||||||
|
ssl_version_max = ssl_version << 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(ssl_version) {
|
||||||
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
|
#ifdef TLS1_3_VERSION
|
||||||
|
SSL_CTX_set_max_proto_version(connssl->ctx, TLS1_3_VERSION);
|
||||||
|
*ctx_options |= SSL_OP_NO_TLSv1_2;
|
||||||
|
#else
|
||||||
|
failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
|
||||||
|
return CURLE_NOT_BUILT_IN;
|
||||||
|
#endif
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
|
||||||
|
*ctx_options |= SSL_OP_NO_TLSv1_1;
|
||||||
|
#else
|
||||||
|
failf(data, OSSL_PACKAGE " was built without TLS 1.2 support");
|
||||||
|
return CURLE_NOT_BUILT_IN;
|
||||||
|
#endif
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
|
||||||
|
*ctx_options |= SSL_OP_NO_TLSv1;
|
||||||
|
#else
|
||||||
|
failf(data, OSSL_PACKAGE " was built without TLS 1.1 support");
|
||||||
|
return CURLE_NOT_BUILT_IN;
|
||||||
|
#endif
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
*ctx_options |= SSL_OP_NO_SSLv2;
|
||||||
|
*ctx_options |= SSL_OP_NO_SSLv3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(ssl_version_max) {
|
||||||
|
case CURL_SSLVERSION_MAX_TLSv1_0:
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
|
||||||
|
*ctx_options |= SSL_OP_NO_TLSv1_1;
|
||||||
|
#endif
|
||||||
|
case CURL_SSLVERSION_MAX_TLSv1_1:
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
|
||||||
|
*ctx_options |= SSL_OP_NO_TLSv1_2;
|
||||||
|
#endif
|
||||||
|
case CURL_SSLVERSION_MAX_TLSv1_2:
|
||||||
|
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
#ifdef TLS1_3_VERSION
|
||||||
|
*ctx_options |= SSL_OP_NO_TLSv1_3;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_MAX_TLSv1_3:
|
||||||
|
#ifdef TLS1_3_VERSION
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
|
||||||
|
return CURLE_NOT_BUILT_IN;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
@ -1701,7 +1766,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
|||||||
X509_LOOKUP *lookup = NULL;
|
X509_LOOKUP *lookup = NULL;
|
||||||
curl_socket_t sockfd = conn->sock[sockindex];
|
curl_socket_t sockfd = conn->sock[sockindex];
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
long ctx_options;
|
long ctx_options = 0;
|
||||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||||
bool sni;
|
bool sni;
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
@ -1888,60 +1953,13 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
ctx_options |= SSL_OP_NO_SSLv2;
|
|
||||||
ctx_options |= SSL_OP_NO_SSLv3;
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1_1;
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1_2;
|
|
||||||
#ifdef TLS1_3_VERSION
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1_3;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
|
|
||||||
ctx_options |= SSL_OP_NO_SSLv2;
|
|
||||||
ctx_options |= SSL_OP_NO_SSLv3;
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1;
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1_2;
|
|
||||||
#ifdef TLS1_3_VERSION
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1_3;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
failf(data, OSSL_PACKAGE " was built without TLS 1.1 support");
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
|
|
||||||
ctx_options |= SSL_OP_NO_SSLv2;
|
|
||||||
ctx_options |= SSL_OP_NO_SSLv3;
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1;
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1_1;
|
|
||||||
#ifdef TLS1_3_VERSION
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1_3;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
failf(data, OSSL_PACKAGE " was built without TLS 1.2 support");
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
#ifdef TLS1_3_VERSION
|
result = set_ssl_version_min_max(&ctx_options, conn);
|
||||||
SSL_CTX_set_max_proto_version(connssl->ctx, TLS1_3_VERSION);
|
if(result != CURLE_OK)
|
||||||
ctx_options |= SSL_OP_NO_SSLv2;
|
return result;
|
||||||
ctx_options |= SSL_OP_NO_SSLv3;
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1;
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1_1;
|
|
||||||
ctx_options |= SSL_OP_NO_TLSv1_2;
|
|
||||||
break;
|
break;
|
||||||
#else
|
|
||||||
failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
|
|
||||||
return CURLE_NOT_BUILT_IN;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case CURL_SSLVERSION_SSLv2:
|
case CURL_SSLVERSION_SSLv2:
|
||||||
#ifndef OPENSSL_NO_SSL2
|
#ifndef OPENSSL_NO_SSL2
|
||||||
|
@ -140,6 +140,68 @@ static void polarssl_debug(void *context, int level, const char *line)
|
|||||||
static Curl_recv polarssl_recv;
|
static Curl_recv polarssl_recv;
|
||||||
static Curl_send polarssl_send;
|
static Curl_send polarssl_send;
|
||||||
|
|
||||||
|
static CURLcode polarssl_version_from_curl(int *polarver, long version)
|
||||||
|
{
|
||||||
|
switch(ssl_version) {
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
*polarver = SSL_MINOR_VERSION_1;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
*polarver = SSL_MINOR_VERSION_2;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
*polarver = SSL_MINOR_VERSION_3;
|
||||||
|
return CURLE_OK;
|
||||||
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
set_ssl_version_min_max(struct connectdata *conn, int sockindex);
|
||||||
|
{
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
|
||||||
|
long ssl_version = SSL_CONN_CONFIG(version);
|
||||||
|
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||||
|
int ssl_min_ver = SSL_MINOR_VERSION_1;
|
||||||
|
int ssl_max_ver = SSL_MINOR_VERSION_1;
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
|
switch(ssl_version) {
|
||||||
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
ssl_version = CURL_SSLVERSION_TLSv1_0;
|
||||||
|
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(ssl_version_max) {
|
||||||
|
case CURL_SSLVERSION_MAX_NONE:
|
||||||
|
ssl_version_max = ssl_version << 16;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = polarssl_version_from_curl(&ssl_min_ver, ssl_version);
|
||||||
|
if(result) {
|
||||||
|
failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = polarssl_version_from_curl(&ssl_max_ver, ssl_version_max >> 16);
|
||||||
|
if(result) {
|
||||||
|
failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver);
|
||||||
|
ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
polarssl_connect_step1(struct connectdata *conn,
|
polarssl_connect_step1(struct connectdata *conn,
|
||||||
@ -287,29 +349,15 @@ polarssl_connect_step1(struct connectdata *conn,
|
|||||||
infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
|
infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
|
|
||||||
SSL_MINOR_VERSION_1);
|
|
||||||
ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
|
|
||||||
SSL_MINOR_VERSION_1);
|
|
||||||
infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.0\n");
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
|
|
||||||
SSL_MINOR_VERSION_2);
|
|
||||||
ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
|
|
||||||
SSL_MINOR_VERSION_2);
|
|
||||||
infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.1\n");
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
|
|
||||||
SSL_MINOR_VERSION_3);
|
|
||||||
ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
|
|
||||||
SSL_MINOR_VERSION_3);
|
|
||||||
infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n");
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
failf(data, "PolarSSL: TLS 1.3 is not yet supported");
|
{
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
CURLcode result = set_ssl_version_min_max(conn, sockindex);
|
||||||
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
@ -102,6 +102,41 @@ static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
|
|||||||
desc->cBuffers = NumArrElem;
|
desc->cBuffers = NumArrElem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CURLcode
|
||||||
|
set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn)
|
||||||
|
{
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
long ssl_version = SSL_CONN_CONFIG(version);
|
||||||
|
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||||
|
long i = ssl_version;
|
||||||
|
|
||||||
|
switch(ssl_version_max) {
|
||||||
|
case CURL_SSLVERSION_MAX_NONE:
|
||||||
|
ssl_version_max = ssl_version << 16;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(; i <= (ssl_version_max >> 16); ++i) {
|
||||||
|
switch(i) {
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
|
failf(data, "Schannel: TLS 1.3 is not yet supported");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
schannel_connect_step1(struct connectdata *conn, int sockindex)
|
schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
@ -216,17 +251,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
|||||||
SP_PROT_TLS1_2_CLIENT;
|
SP_PROT_TLS1_2_CLIENT;
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1_0:
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_1:
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
failf(data, "Schannel: TLS 1.3 is not yet supported");
|
{
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
CURLcode result = set_ssl_version_min_max(&schannel_cred, conn);
|
||||||
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
|
schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
|
||||||
break;
|
break;
|
||||||
|
@ -95,6 +95,7 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
|
|||||||
struct ssl_primary_config* needle)
|
struct ssl_primary_config* needle)
|
||||||
{
|
{
|
||||||
if((data->version == needle->version) &&
|
if((data->version == needle->version) &&
|
||||||
|
(data->version_max == needle->version_max) &&
|
||||||
(data->verifypeer == needle->verifypeer) &&
|
(data->verifypeer == needle->verifypeer) &&
|
||||||
(data->verifyhost == needle->verifyhost) &&
|
(data->verifyhost == needle->verifyhost) &&
|
||||||
Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
|
Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
|
||||||
@ -113,6 +114,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
|
|||||||
dest->verifyhost = source->verifyhost;
|
dest->verifyhost = source->verifyhost;
|
||||||
dest->verifypeer = source->verifypeer;
|
dest->verifypeer = source->verifypeer;
|
||||||
dest->version = source->version;
|
dest->version = source->version;
|
||||||
|
dest->version_max = source->version_max;
|
||||||
|
|
||||||
CLONE_STRING(CAfile);
|
CLONE_STRING(CAfile);
|
||||||
CLONE_STRING(CApath);
|
CLONE_STRING(CApath);
|
||||||
@ -173,11 +175,24 @@ void Curl_ssl_cleanup(void)
|
|||||||
static bool ssl_prefs_check(struct Curl_easy *data)
|
static bool ssl_prefs_check(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
/* check for CURLOPT_SSLVERSION invalid parameter value */
|
/* check for CURLOPT_SSLVERSION invalid parameter value */
|
||||||
if((data->set.ssl.primary.version < 0)
|
const long sslver = data->set.ssl.primary.version;
|
||||||
|| (data->set.ssl.primary.version >= CURL_SSLVERSION_LAST)) {
|
if((sslver < 0) || (sslver >= CURL_SSLVERSION_LAST)) {
|
||||||
failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION");
|
failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch(data->set.ssl.primary.version_max) {
|
||||||
|
case CURL_SSLVERSION_MAX_NONE:
|
||||||
|
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if((data->set.ssl.primary.version_max >> 16) < sslver) {
|
||||||
|
failf(data, "CURL_SSLVERSION_MAX incompatible with CURL_SSLVERSION");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +262,16 @@
|
|||||||
d c 6
|
d c 6
|
||||||
d CURL_SSLVERSION_TLSv1_3...
|
d CURL_SSLVERSION_TLSv1_3...
|
||||||
d c 7
|
d c 7
|
||||||
|
d CURL_SSLVERSION_MAX_DEFAULT...
|
||||||
|
d c X'00010000'
|
||||||
|
d CURL_SSLVERSION_MAX_TLSv1_0...
|
||||||
|
d c X'00040000'
|
||||||
|
d CURL_SSLVERSION_MAX_TLSv1_1...
|
||||||
|
d c X'00050000'
|
||||||
|
d CURL_SSLVERSION_MAX_TLSv1_2...
|
||||||
|
d c X'00060000'
|
||||||
|
d CURL_SSLVERSION_MAX_TLSv1_3...
|
||||||
|
d c X'00070000'
|
||||||
*
|
*
|
||||||
d CURL_TLSAUTH_NONE...
|
d CURL_TLSAUTH_NONE...
|
||||||
d c 0
|
d c 0
|
||||||
|
@ -156,6 +156,7 @@ struct OperationConfig {
|
|||||||
struct curl_slist *postquote;
|
struct curl_slist *postquote;
|
||||||
struct curl_slist *prequote;
|
struct curl_slist *prequote;
|
||||||
long ssl_version;
|
long ssl_version;
|
||||||
|
long ssl_version_max;
|
||||||
long proxy_ssl_version;
|
long proxy_ssl_version;
|
||||||
long ip_version;
|
long ip_version;
|
||||||
curl_TimeCond timecond;
|
curl_TimeCond timecond;
|
||||||
|
@ -184,6 +184,7 @@ static const struct LongShort aliases[]= {
|
|||||||
{"$S", "tftp-no-options", FALSE},
|
{"$S", "tftp-no-options", FALSE},
|
||||||
{"$U", "connect-to", TRUE},
|
{"$U", "connect-to", TRUE},
|
||||||
{"$W", "abstract-unix-socket", TRUE},
|
{"$W", "abstract-unix-socket", TRUE},
|
||||||
|
{"$X", "tls-max", TRUE},
|
||||||
{"0", "http1.0", FALSE},
|
{"0", "http1.0", FALSE},
|
||||||
{"01", "http1.1", FALSE},
|
{"01", "http1.1", FALSE},
|
||||||
{"02", "http2", FALSE},
|
{"02", "http2", FALSE},
|
||||||
@ -1060,6 +1061,11 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
config->abstract_unix_socket = TRUE;
|
config->abstract_unix_socket = TRUE;
|
||||||
GetStr(&config->unix_socket_path, nextarg);
|
GetStr(&config->unix_socket_path, nextarg);
|
||||||
break;
|
break;
|
||||||
|
case 'X': /* --tls-max */
|
||||||
|
err = str2tls_max(&config->ssl_version_max, nextarg);
|
||||||
|
if(err)
|
||||||
|
return err;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '#': /* --progress-bar */
|
case '#': /* --progress-bar */
|
||||||
|
@ -260,6 +260,7 @@ static const char *const helptext[] = {
|
|||||||
" --tlsv1.1 Use TLSv1.1 (SSL)",
|
" --tlsv1.1 Use TLSv1.1 (SSL)",
|
||||||
" --tlsv1.2 Use TLSv1.2 (SSL)",
|
" --tlsv1.2 Use TLSv1.2 (SSL)",
|
||||||
" --tlsv1.3 Use TLSv1.3 (SSL)",
|
" --tlsv1.3 Use TLSv1.3 (SSL)",
|
||||||
|
" --tls-max VERSION Use TLS up to VERSION (SSL)",
|
||||||
" --trace FILE Write a debug trace to FILE",
|
" --trace FILE Write a debug trace to FILE",
|
||||||
" --trace-ascii FILE Like --trace, but without hex output",
|
" --trace-ascii FILE Like --trace, but without hex output",
|
||||||
" --trace-time Add time stamps to trace/verbose output",
|
" --trace-time Add time stamps to trace/verbose output",
|
||||||
|
@ -1087,7 +1087,8 @@ static CURLcode operate_do(struct GlobalConfig *global,
|
|||||||
if(config->falsestart)
|
if(config->falsestart)
|
||||||
my_setopt(curl, CURLOPT_SSL_FALSESTART, 1L);
|
my_setopt(curl, CURLOPT_SSL_FALSESTART, 1L);
|
||||||
|
|
||||||
my_setopt_enum(curl, CURLOPT_SSLVERSION, config->ssl_version);
|
my_setopt_enum(curl, CURLOPT_SSLVERSION,
|
||||||
|
config->ssl_version | config->ssl_version_max);
|
||||||
my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION,
|
my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION,
|
||||||
config->proxy_ssl_version);
|
config->proxy_ssl_version);
|
||||||
}
|
}
|
||||||
|
@ -550,3 +550,36 @@ CURLcode get_args(struct OperationConfig *config, const size_t i)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the string and modify ssl_version in the val argument. Return PARAM_OK
|
||||||
|
* on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
|
||||||
|
*
|
||||||
|
* Since this function gets called with the 'nextarg' pointer from within the
|
||||||
|
* getparameter a lot, we must check it for NULL before accessing the str
|
||||||
|
* data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ParameterError str2tls_max(long *val, const char *str)
|
||||||
|
{
|
||||||
|
static struct s_tls_max {
|
||||||
|
const char *tls_max_str;
|
||||||
|
long 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 }
|
||||||
|
};
|
||||||
|
size_t i = 0;
|
||||||
|
if(!str)
|
||||||
|
return PARAM_REQUIRES_PARAMETER;
|
||||||
|
for(i = 0; i < sizeof(tls_max_array)/sizeof(tls_max_array[0]); i++) {
|
||||||
|
if(!strcmp(str, tls_max_array[i].tls_max_str)) {
|
||||||
|
*val = tls_max_array[i].tls_max;
|
||||||
|
return PARAM_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PARAM_BAD_USE;
|
||||||
|
}
|
||||||
|
@ -52,4 +52,6 @@ int ftpcccmethod(struct OperationConfig *config, const char *str);
|
|||||||
|
|
||||||
long delegation(struct OperationConfig *config, char *str);
|
long delegation(struct OperationConfig *config, char *str);
|
||||||
|
|
||||||
|
ParameterError str2tls_max(long *val, const char *str);
|
||||||
|
|
||||||
#endif /* HEADER_CURL_TOOL_PARAMHLP_H */
|
#endif /* HEADER_CURL_TOOL_PARAMHLP_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user