#27 Request option to disable SSLv2

open
libcurl (29)
2012-12-12
2007-08-03
Scott Cantor
No

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.

Discussion

  • 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...

     
  • Scott Cantor
    Scott Cantor
    2007-08-03

    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...

     
  • Scott Cantor
    Scott Cantor
    2007-08-03

    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

     
  • Kaspar
    Kaspar
    2008-02-17

    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!