2

I am trying to find out if there's a way to upgrade the SSL version from SSLv3 to TLSv1 of a connection by only making server-side changes.

In my case, both the client application and server are using OpenSSL(v0.9.8o), so both support SSL versions up to TLSv1. Every time the client wishes to establish a connection with the server it uses SSLv3.0 by default when it starts the SSL handshake (i.e. ClientHello, Version 3.0) and thus a connection is established with the server using SSLv3.0.

Edit: The the default SSL version on the client application is hard coded to SSLv3.0.

Without making any client-side code changes, is there a way to upgrade the connection to TLSv1 by only making server-side code changes. Perhaps by using SSL renegotiation?

Note: Of course, changing the default version of the client application so that it initiates the handshake using TLSv1 does establish a TLSv1 connection successfully, however, that is not an option in my case for various reasons.

Any references are very much appreciated. Thanks for your help.

jaybird19
  • 23
  • 1
  • 4
  • "..using OpenSSL(v0.9.8o), so both support SSL versions up to TLSv1.2" - 0.9.8 supports up to TLSv1, TLSv1_1+ was added with OpenSSL 1.0.1. – Steffen Ullrich Dec 16 '14 at 22:24

3 Answers3

1

Something is amiss on the client side it sounds like.

The client should initiate the session indicating the highest protocol version it can accept.

TLS v1 is enumerated as "3.1" to indicate > SSL3:

Since the Version numbers negotiated in the ClientHello and ServerHello messages of SSL are 3.0 and below, version numbers to be negotiated with TLS and future r evisions will continue by negotiating as version 3.1 or higher. This will be done to denote a revision of SSL 3.0, but to promote backwards compatibility between clients and servers using either SSL or TLS.

Source

Further clarification:

The client MUST declare the highest version it can support, and the server will either accept, offer a lower supported version, or declare PROTOCOL_VERSION and close. From ietf.org:

A TLS server can also receive a ClientHello containing version number smaller than the highest supported version. If the server wishes to negotiate with old clients, it will proceed as appropriate for the highest version supported by the server that is not greater than ClientHello.client_version. For example, if the server supports TLS 1.0, 1.1, and 1.2, and client_version is TLS 1.0, the server will proceed with a TLS 1.0 ServerHello. If server supports (or is willing to use) only versions greater than client_version, it MUST send a "protocol_version" alert message and close the connection.

Digital Chris
  • 836
  • 9
  • 11
  • Thanks for your answer. The default version the client application is using is hard coded to SSLv3.0, that's why the ClientHello uses version 3.0. However, the client does technically support up to TLSv1.2. – jaybird19 Dec 16 '14 at 17:12
  • 2
    As far as I know, there is no spec in the protocol for the server to send LiarLiarPantsOnFireIBetYouReallySupportTLSVersion=3.2 – Digital Chris Dec 16 '14 at 17:19
  • Lol. Appreciate your input. So basically, there is no way to enforce a ServerHello version on the client. Can you confirm this for me? – jaybird19 Dec 16 '14 at 17:24
  • Added further clarification to answer. – Digital Chris Dec 16 '14 at 17:28
  • If only there was a hat for getting marked the correct answer then having it taken away... – Digital Chris Dec 16 '14 at 18:56
1

In the SSL/TLS handshake, the client sends (as part of its ClientHello) the maximum version that it supports; then the server chooses the version that will be used, which should be the highest that the server supports but it not higher than the value sent by the client.

  • If the client sends "SSL 3.0" as highest supported version, then the server is right in using SSL 3.0.

  • If the client only supports SSL 3.0 then you won't get anything else than SSL 3.0.

  • Renegotiations won't change anything. A renegotiation is simply a new handshake. If the client really wants to say "SSL 3.0" in its ClientHello, then it will say it again and again.

  • If the client actually supports ulterior versions (TLS 1.0 or more) but does not say so, then:

    1. The client is buggy or does stupid things, and should be fixed.
    2. Since the client does not follow the standards, it is difficult to reliably assume anything on its behaviour.
    3. Nevertheless, it is conceivable that if the server responds with a higher version (e.g. TLS 1.0), then the client accepts to use it even though it is beyond the value that the client announced.

If the client uses OpenSSL as a shared library (aka a "DLL"), then you might have the option to substitute that OpenSSL DLL with another one that disregards the version number provided by the client, and instead announces what it truly supports. This is a client-side kind of change that does not require changing the code of the client application itself, and thus can be applied even if the source code of that application is not available. It still is an awful hack.

An alternate solution would be to wrap the client inside some kind of client-side proxy, in essence running a Man-in-the-Middle attack.


If you really cannot modify the client in the ways described above, then the best that you can hope for is to choose (on the server) a cipher suite that will minimize the known shortcomings of SSL 3.0. In particular, enforcing a cipher using RC4 will avoid the POODLE attack (but then you will get the known biases in RC4: choose your poison).

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • Really appreciate your clear answer. Can you expound a bit on your point "Nevertheless, it is conceivable that if the server responds with a higher version...". How does one go about making that happen? – jaybird19 Dec 16 '14 at 18:29
  • You would have to alter the code on the server, in the SSL library, at the point where it selects the protocol version based on what the client sends. The modification _should_ be minimal, but of course you have to be able to alter the server code. It also sends you in the uncharted area of "custom protocols" so everything afterwards becomes your fault. – Thomas Pornin Dec 16 '14 at 18:34
0

You can simply disallow the lower level of connection if you don't want it used. When establishing an SSL/TLS connection, the server lets the client know what it can support and the two work out what the best option is.

If the client supports TLS and is being forced in to SSL3.0 then something is likely wrong on the client end (or it may be an older SSL proxy for example). Something along the path isn't allowing for TLS to be chosen or the client's preferences are setup very oddly to choose a lower security connection over a higher security one.

Your best bet is to simply disallow SSL3.0 if you don't want people using it. It is pretty easy for an attacker to force a client in to a lower level of protocol if your server supports it, so your best option is not to support it. This may mean a few people with extremely out of date browsers might not be able to access your site, but leaving it open is potentially compromising to all your visitors.

AJ Henderson
  • 41,816
  • 5
  • 63
  • 110
  • Thanks for your answer. The the default SSL version on the client application is hard coded to SSLv3.0, that's why the ClienHello sends version 3.0. – jaybird19 Dec 16 '14 at 17:48
  • 1
    Disabling SSL3.0 on the server should force it to use a non-default option (or the connection will just fail). It is probably your best bet for forcing it though. – AJ Henderson Dec 16 '14 at 17:51
  • Yes that is correct, however, is it possible to force the non-default version to be higher than the version the ClientHello sends. If the ClientHello's version is SSL3.0, and version SSL3.0 is disabled on the server, can we enforce a ServerHello with SSL3.1? – jaybird19 Dec 16 '14 at 17:57