SSL: protocol version can be specified more precisely

CURL_SSLVERSION_TLSv1_0, CURL_SSLVERSION_TLSv1_1,
CURL_SSLVERSION_TLSv1_2 enum values are added to force exact TLS version
(CURL_SSLVERSION_TLSv1 means TLS 1.x).

axTLS:
axTLS only supports TLS 1.0 and 1.1 but it cannot be set that only one
of these should be used, so we don't allow the new enum values.

darwinssl:
Added support for the new enum values.

SChannel:
Added support for the new enum values.

CyaSSL:
Added support for the new enum values.
Bug: The original CURL_SSLVERSION_TLSv1 value enables only TLS 1.0 (it
did the same before this commit), because CyaSSL cannot be configured to
use TLS 1.0-1.2.

GSKit:
GSKit doesn't seem to support TLS 1.1 and TLS 1.2, so we do not allow
those values.
Bugfix: There was a typo that caused wrong SSL versions to be passed to
GSKit.

NSS:
TLS minor version cannot be set, so we don't allow the new enum values.

QsoSSL:
TLS minor version cannot be set, so we don't allow the new enum values.

OpenSSL:
Added support for the new enum values.
Bugfix: The original CURL_SSLVERSION_TLSv1 value enabled only TLS 1.0,
now it enables 1.0-1.2.

Command-line tool:
Added command line options for the new values.
This commit is contained in:
Gergely Nagy 2013-09-19 15:17:13 +02:00 коммит произвёл Daniel Stenberg
Родитель 31e106c01c
Коммит ad34a2d5c8
14 изменённых файлов: 161 добавлений и 22 удалений

Просмотреть файл

@ -2417,11 +2417,17 @@ The default action. This will attempt to figure out the remote SSL protocol
version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled
by default with 7.18.1).
.IP CURL_SSLVERSION_TLSv1
Force TLSv1
Force TLSv1.x
.IP CURL_SSLVERSION_SSLv2
Force SSLv2
.IP CURL_SSLVERSION_SSLv3
Force SSLv3
.IP CURL_SSLVERSION_TLSv1_0
Force TLSv1.0
.IP CURL_SSLVERSION_TLSv1_1
Force TLSv1.1
.IP CURL_SSLVERSION_TLSv1_2
Force TLSv1.2
.RE
.IP CURLOPT_SSL_VERIFYPEER
Pass a long as parameter. By default, curl assumes a value of 1.

Просмотреть файл

@ -695,6 +695,9 @@ CURL_SSLVERSION_DEFAULT 7.9.2
CURL_SSLVERSION_SSLv2 7.9.2
CURL_SSLVERSION_SSLv3 7.9.2
CURL_SSLVERSION_TLSv1 7.9.2
CURL_SSLVERSION_TLSv1_0 7.33.0
CURL_SSLVERSION_TLSv1_1 7.33.0
CURL_SSLVERSION_TLSv1_2 7.33.0
CURL_TIMECOND_IFMODSINCE 7.9.7
CURL_TIMECOND_IFUNMODSINCE 7.9.7
CURL_TIMECOND_LASTMOD 7.9.7

Просмотреть файл

@ -1659,9 +1659,12 @@ enum CURL_NETRC_OPTION {
enum {
CURL_SSLVERSION_DEFAULT,
CURL_SSLVERSION_TLSv1,
CURL_SSLVERSION_TLSv1, /* TLS 1.x */
CURL_SSLVERSION_SSLv2,
CURL_SSLVERSION_SSLv3,
CURL_SSLVERSION_TLSv1_0,
CURL_SSLVERSION_TLSv1_1,
CURL_SSLVERSION_TLSv1_2,
CURL_SSLVERSION_LAST /* never use, keep last */
};

Просмотреть файл

@ -164,7 +164,8 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
case CURL_SSLVERSION_TLSv1:
break;
default:
failf(data, "axTLS only supports TLSv1");
failf(data, "axTLS only supports TLS 1.0 and 1.1, "
"and it cannot be specified which one to use");
return CURLE_SSL_CONNECT_ERROR;
}

Просмотреть файл

@ -1056,6 +1056,18 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
break;
case CURL_SSLVERSION_TLSv1_0:
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
break;
case CURL_SSLVERSION_TLSv1_1:
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
break;
case CURL_SSLVERSION_TLSv1_2:
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
break;
case CURL_SSLVERSION_SSLv3:
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
@ -1100,6 +1112,21 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
kTLSProtocol12,
true);
break;
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_SSLv3:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol3,
@ -1130,10 +1157,17 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kTLSProtocol1,
true);
break;
case CURL_SSLVERSION_TLSv1_1:
failf(data, "Your version of the OS does not support TLSv1.1");
return CURLE_SSL_CONNECT_ERROR;
case CURL_SSLVERSION_TLSv1_2:
failf(data, "Your version of the OS does not support TLSv1.2");
return CURLE_SSL_CONNECT_ERROR;
case CURL_SSLVERSION_SSLv2:
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol2,

Просмотреть файл

@ -180,6 +180,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
SP_PROT_TLS1_1_CLIENT |
SP_PROT_TLS1_2_CLIENT;
break;
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_SSLv3:
schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
break;

Просмотреть файл

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -98,8 +98,19 @@ cyassl_connect_step1(struct connectdata *conn,
req_method = SSLv23_client_method();
break;
case CURL_SSLVERSION_TLSv1:
infof(data, "CyaSSL cannot be configured to use TLS 1.0-1.2, "
"TLS 1.0 is used exclusively\n");
req_method = TLSv1_client_method();
break;
case CURL_SSLVERSION_TLSv1_0:
req_method = TLSv1_client_method();
break;
case CURL_SSLVERSION_TLSv1_1:
req_method = TLSv1_1_client_method();
break;
case CURL_SSLVERSION_TLSv1_2:
req_method = TLSv1_2_client_method();
break;
case CURL_SSLVERSION_SSLv3:
req_method = SSLv3_client_method();
break;

Просмотреть файл

@ -503,8 +503,17 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
sni = (char *) NULL;
break;
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
tlsv1enable = true;
break;
case CURL_SSLVERSION_TLSv1_1:
failf(data, "GSKit doesn't support TLS 1.1!");
cc = CURLE_SSL_CONNECT_ERROR;
break;
case CURL_SSLVERSION_TLSv1_2:
failf(data, "GSKit doesn't support TLS 1.2!");
cc = CURLE_SSL_CONNECT_ERROR;
break;
default: /* CURL_SSLVERSION_DEFAULT. */
sslv3enable = true;
tlsv1enable = true;
@ -555,7 +564,7 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
GSK_PROTOCOL_SSLV3_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
sslv3enable? GSK_PROTOCOL_TLSV1_ON:
tlsv1enable? GSK_PROTOCOL_TLSV1_ON:
GSK_PROTOCOL_TLSV1_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,

Просмотреть файл

@ -1267,6 +1267,12 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
case CURL_SSLVERSION_SSLv3:
ssl3 = PR_TRUE;
break;
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
failf(data, "TLS minor version cannot be set\n");
curlerr = CURLE_SSL_CONNECT_ERROR;
goto error;
}
if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess)

Просмотреть файл

@ -204,6 +204,12 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
case CURL_SSLVERSION_SSLv3:
h->protocol = SSL_VERSION_3;
break;
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
failf(data, "TLS minor version cannot be set");
return CURLE_SSL_CONNECT_ERROR;
}
h->peerCert = NULL;

Просмотреть файл

@ -1431,19 +1431,12 @@ ossl_connect_step1(struct connectdata *conn,
switch(data->set.ssl.version) {
default:
case CURL_SSLVERSION_DEFAULT:
#ifdef USE_TLS_SRP
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
infof(data, "Set version TLSv1 for SRP authorisation\n");
req_method = TLSv1_client_method() ;
}
else
#endif
/* we try to figure out version */
req_method = SSLv23_client_method();
use_sni(TRUE);
break;
case CURL_SSLVERSION_TLSv1:
req_method = TLSv1_client_method();
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
/* it will be handled later with the context options */
req_method = SSLv23_client_method();
use_sni(TRUE);
break;
case CURL_SSLVERSION_SSLv2:
@ -1556,9 +1549,39 @@ ossl_connect_step1(struct connectdata *conn,
ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
/* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
switch(data->set.ssl.version) {
case CURL_SSLVERSION_DEFAULT:
ctx_options |= SSL_OP_NO_SSLv2;
#ifdef USE_TLS_SRP
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
infof(data, "Set version TLSv1.x for SRP authorisation\n");
ctx_options |= SSL_OP_NO_SSLv3;
}
#endif
break;
case CURL_SSLVERSION_TLSv1:
ctx_options |= SSL_OP_NO_SSLv2;
ctx_options |= SSL_OP_NO_SSLv3;
break;
case CURL_SSLVERSION_TLSv1_0:
ctx_options |= SSL_OP_NO_SSLv2;
ctx_options |= SSL_OP_NO_SSLv3;
ctx_options |= SSL_OP_NO_TLSv1_1;
ctx_options |= SSL_OP_NO_TLSv1_2;
break;
case CURL_SSLVERSION_TLSv1_1:
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;
break;
case CURL_SSLVERSION_TLSv1_2:
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;
break;
}
SSL_CTX_set_options(connssl->ctx, ctx_options);

Просмотреть файл

@ -228,6 +228,12 @@
d c 2
d CURL_SSLVERSION_SSLv3...
d c 3
d CURL_SSLVERSION_TLSv1_0...
d c 4
d CURL_SSLVERSION_TLSv1_1...
d c 5
d CURL_SSLVERSION_TLSv1_2...
d c 6
*
d CURL_TLSAUTH_NONE...
d c 0

Просмотреть файл

@ -184,6 +184,9 @@ static const struct LongShort aliases[]= {
{"01", "http1.1", FALSE},
{"02", "http2.0", FALSE},
{"1", "tlsv1", FALSE},
{"10", "tlsv1.0", FALSE},
{"11", "tlsv1.1", FALSE},
{"12", "tlsv1.2", FALSE},
{"2", "sslv2", FALSE},
{"3", "sslv3", FALSE},
{"4", "ipv4", FALSE},
@ -1023,9 +1026,25 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
break;
}
break;
case '1':
/* TLS version 1 */
config->ssl_version = CURL_SSLVERSION_TLSv1;
case '1': /* --tlsv1* options */
switch(subletter) {
case '\0':
/* TLS version 1.x */
config->ssl_version = CURL_SSLVERSION_TLSv1;
break;
case '0':
/* TLS version 1.0 */
config->ssl_version = CURL_SSLVERSION_TLSv1_0;
break;
case '1':
/* TLS version 1.1 */
config->ssl_version = CURL_SSLVERSION_TLSv1_1;
break;
case '2':
/* TLS version 1.2 */
config->ssl_version = CURL_SSLVERSION_TLSv1_2;
break;
}
break;
case '2':
/* SSL version 2 */

Просмотреть файл

@ -78,6 +78,9 @@ const NameValue setopt_nv_CURL_SSLVERSION[] = {
NV(CURL_SSLVERSION_TLSv1),
NV(CURL_SSLVERSION_SSLv2),
NV(CURL_SSLVERSION_SSLv3),
NV(CURL_SSLVERSION_TLSv1_0),
NV(CURL_SSLVERSION_TLSv1_1),
NV(CURL_SSLVERSION_TLSv1_2),
NVEND,
};