6

We have an issue where a client application, that has TLS 1.0, 1.1 and 1.2 enabled cannot connect to a server using only TLS 1.0.

After disabling TLS 1.2 and 1.1 on the client the connection can be made.

So i was wondering; how is the TLS version to use determined between client and server?

oɔɯǝɹ
  • 538
  • 2
  • 6
  • 18

2 Answers2

16

Seems that your application (client side) does not accept version negotiation fallback during the SSL/TLS session establishment.

The TLS version is negotiated initially by the client (Client Hello message) specifing the highest version that it supports among other parameters (cipher parameters, etc.). Text from RFC 5246, TLS v1.2:

client_version: The version of the TLS protocol by which the client wishes to communicate during this session. This SHOULD be the latest (highest valued) version supported by the client. For this version of the specification, the version will be 3.3 (see Appendix E for details about backward compatibility).

After the server receives the Client Hello it sends the Server Hello with the chosen SSL/TLS version among other chosen parameters based on the Client Hello information. Text from RFC 5246, TLS v1.2:

server_version: This field will contain the lower of that suggested by the client in the client hello and the highest supported by the server. For this version of the specification, the version is 3.3. (See Appendix E for details about backward compatibility.)

A summary of all this is shown in the following diagram: TLS Negotiation, RedHat,  (https://access.redhat.com/sites/default/files/styles/large/public/tls-handshake_1.png?itok=3B6sTz23)

I would say the problem is that your Client application does not accept TLS version downgrade fallback during the negotiation and that's why it works when disabling TLSv1.1 and TLSv1.2. Check the bold text in the again RFC 5246, Appendix E:

A TLS 1.2 client who wishes to negotiate with such older servers will send a normal TLS 1.2 ClientHello, containing { 3, 3 } (TLS 1.2) in
ClientHello.client_version. If the server does not support this
version, it will respond with a ServerHello containing an older
version number. If the client agrees to use this version, the
negotiation will proceed as appropriate for the negotiated protocol.

If the version chosen by the server is not supported by the client (or not acceptable), the client MUST send a "protocol_version" alert
message and close the connection.

An easy approach to debug this, could be to check the logs of both server and application (you did not specify which applications you're using) in verbose mode so you can see the negotation messages. Other more advanced may be to put wirehark/tcpdump to check the negotation parameters. This should be feasible without too much hassle since these information does not travel encrypted.

b0rt
  • 335
  • 1
  • 4
  • 1
    Since TLS 1.0 support is enabled at the client according to the OP it is more likely that a broken server cannot deal with the client announcing support for TLS 1.2. But for the exact reason one would need to see the more details, especially which side throws the error or closes the connection. – Steffen Ullrich Aug 29 '17 at 10:43
2

Most programs today try to use the highest possible version when trying to connect. If that fails, they go back a version until a supported version is found at the other end. If the program is not smart enough to automatically do that, you will need to manually tell him to use an older version (like you practically did in your case).

Overmind
  • 8,829
  • 3
  • 19
  • 28