The current version selection option for SSL lets the caller turn on a specific SSL/TLS version, but not disable one. Normally SSLv3 and TLSv1 would both be acceptable, but SSLv2 is never acceptable because of its holes, so it would be good to have the option to allow anything but that version.
(We've tested that disabling the SSLv2 ciphers doesn't actually disable use of SSLv2 itself.)
I checked the openssl s_client options, and it supports turning off a specific version, so apparently it can be done.
Logged In: YES
user_id=1110
Originator: NO
How does the s_client support this? (I mean option/command etc)
I don't find any easy API for this in the OpenSSL docs, so possibly the lib would have to do a version check after a connect has been performed and then close down again if using the wrong version...
Logged In: YES
user_id=96701
Originator: YES
I don't know how it does it internally (haven't looked yet), but the flag is here:
$ openssl s_client help
...
-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol
...
I wouldn't have asked if I hadn't seen the option, I was expecting it had the same limitation libcurl did but then I saw it listed, so at least there's code we could copy from the sample tool.
It's probably not worth the hassle if it takes anything exotic that could create regressions, but if there's a simple API it would be worth it.
Logged In: YES
user_id=1110
Originator: NO
Thanks, that lead me exactly to the right place.
It seems SSL_CTX_set_options() (that libcurl already uses) has bits to disable specific protocols:
SSL_OP_NO_SSLv2
Do not use the SSLv2 protocol.
SSL_OP_NO_SSLv3
Do not use the SSLv3 protocol.
SSL_OP_NO_TLSv1
Do not use the TLSv1 protocol.
So yes, this should be fairly easy to support for OpenSSL at least...
Logged In: YES
user_id=96701
Originator: YES
Quick update...it uses SSL_CTX_set_options using some bit flags that turn off specific protocols, you'll see it in s_client.c. It looks like it only works with "non-buggy" servers, but that's not too surprising.
Don't know how far back the option exists, I'm looking at 0.9.8
Logged In: YES
user_id=1854294
Originator: NO
From http://curl.haxx.se/mail/lib-2008-02/0114.html:
> > I think starting disabling ssl2 by default is also a good thing today.
>
> I agree. Related feature request:
> http://sourceforge.net/tracker/index.php?func=detail&aid=1767276&group_id=976&atid=350976
While not exactly addressing the original request, here's a patch which disables SSLv2 when CURL_SSLVERSION_DEFAULT is used (couldn't figure out how to attach the file separately - maybe because I'm neither the reporter nor the assignee?).
It includes the changes for all SSL toolkits currently supported by curl. Note that for NSS, this will "automagically" turn on TLS extensions (server name indication/SNI e.g.), if compiled against 3.11 or later. For GnuTLS, no changes are needed - SSLv2 isn't implemented in that library on purpose.
Index: lib/ssluse.c
RCS file: /cvsroot/curl/curl/lib/ssluse.c,v
retrieving revision 1.192
diff -u -p -r1.192 ssluse.c
--- lib/ssluse.c 7 Feb 2008 22:25:04 -0000 1.192
+++ lib/ssluse.c 17 Feb 2008 15:12:54 -0000
@@ -1324,6 +1331,10 @@ ossl_connect_step1(struct connectdata *c
*/
SSL_CTX_set_options(connssl->ctx, SSL_OP_ALL);
+ /* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
+ if (data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
+ SSL_CTX_set_options(connssl->ctx, SSL_OP_NO_SSLv2);
+
#if 0
/*
* Not sure it's needed to tell SSL_connect() that socket is
Index: lib/nss.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/nss.c,v
retrieving revision 1.15
diff -u -p -r1.15 nss.c
--- lib/nss.c 15 Jan 2008 23:19:02 -0000 1.15
+++ lib/nss.c 17 Feb 2008 15:12:54 -0000
@@ -873,7 +873,7 @@ CURLcode Curl_nss_connect(struct connect
switch (data->set.ssl.version) {
default:
case CURL_SSLVERSION_DEFAULT:
- ssl2 = ssl3 = tlsv1 = PR_TRUE;
+ ssl3 = tlsv1 = PR_TRUE;
break;
case CURL_SSLVERSION_TLSv1:
tlsv1 = PR_TRUE;
@@ -893,6 +893,9 @@ CURLcode Curl_nss_connect(struct connect
if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess)
goto error;
+ if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess)
+ goto error;
+
if(data->set.ssl.cipher_list) {
if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
curlerr = CURLE_SSL_CIPHER;
Index: lib/qssl.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/qssl.c,v
retrieving revision 1.9
diff -u -p -r1.9 qssl.c
--- lib/qssl.c 11 Feb 2008 22:03:31 -0000 1.9
+++ lib/qssl.c 17 Feb 2008 15:12:54 -0000
@@ -90,7 +90,7 @@ static CURLcode Curl_qsossl_init_session
memset((char *) &initappstr, 0, sizeof initappstr);
initappstr.applicationID = certname;
initappstr.applicationIDLen = strlen(certname);
- initappstr.protocol = SSL_VERSION_CURRENT;
+ initappstr.protocol = TLSV1_SSLV3;
initappstr.sessionType = SSL_REGISTERED_AS_CLIENT;
rc = SSL_Init_Application(&initappstr);
@@ -190,7 +190,7 @@ static CURLcode Curl_qsossl_handshake(st
default:
case CURL_SSLVERSION_DEFAULT:
- h->protocol = SSL_VERSION_CURRENT;
+ h->protocol = TLSV1_SSLV3;
break;
case CURL_SSLVERSION_TLSv1:
Index: docs/libcurl/curl_easy_setopt.3
===================================================================
RCS file: /cvsroot/curl/curl/docs/libcurl/curl_easy_setopt.3,v
retrieving revision 1.211
diff -u -p -r1.211 curl_easy_setopt.3
--- docs/libcurl/curl_easy_setopt.3 11 Jan 2008 14:20:41 -0000 1.211
+++ docs/libcurl/curl_easy_setopt.3 17 Feb 2008 15:12:54 -0000
@@ -1379,10 +1379,9 @@ Pass a long as parameter to control what
The available options are:
.RS
.IP CURL_SSLVERSION_DEFAULT
-The default action. When libcurl built with OpenSSL or NSS, this will attempt
-to figure out the remote SSL protocol version. Unfortunately there are a lot of
-ancient and broken servers in use which cannot handle this technique and will
-fail to connect. When libcurl is built with GnuTLS, this will mean SSLv3.
+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
.IP CURL_SSLVERSION_SSLv2
Logged In: YES
user_id=1110
Originator: NO
Kaspar, can you please post the patch to the curl-library mailing list instead? I'd like to apply it, but it breaks really badly when pasted like this!