Version negotiation failure failure?

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Version negotiation failure failure?

JordanBrown

We're trying to nail down error reporting for TLS version mismatches, and we're seeing a couple of puzzling behaviors.

First, and most puzzling... assume these two command lines:

$ openssl s_server -cert 2018.08.31.a.pem -key 2018.08.31.a.key -no_tls1

$ openssl s_client -connect zel.us.oracle.com:4433 -tls1

That is, I have a server that won't accept TLSv1.0, and a client that will only accept TLSv1.0.

On the server side I see

1:error:14076102:SSL routines:SSL23_GET_CLIENT_HELLO:unsupported protocol:s23_srvr.c:605:

which makes perfect sense.  On the client side I see

4294956672:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:

which isn't as good, but is still sort of sensible.  But when I look at the packets exchanged, I see that the client sends a Client Hello, and the server responds with an ACK and then a FIN-ACK, with no data.  It just hangs up the phone.  This seems to violate RFC 5246 section E.1:  "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.".  Where's my protocol version alert?

Of course my real case does not involve the sample client and server - it involves my own clients and servers - but I seem to see the same behavior with several servers (notably including the Apache httpd).

This looks like it's the same as https://rt.openssl.org/Ticket/Display.html?id=2777 .  I'm using 1.0.2o.  (But I don't see anything relevant-looking in the 1.0.2p changes.)  I've seen similar behavior from 1.0.2o-fips.

Am I missing something here, or is this a server-side bug?


And then, on the client side...

SSL_connect returns zero.  Exactly how that failure differs from a less-than-zero error is not clear, but OK.  The docs say to call SSL_get_error().  SSL_get_error() returns 5, SSL_ERROR_SYSCALL.  (That seems a little strange, since I don't think there's any system call errors here.)  The docs say to consult the error queue and errno.  ERR_peek_last_error( ) returns zero.  Errno is zero.  It failed, but nobody will tell me why.

Am I missing something here, or is this a client library bug?


(I have not tracked down exactly how the s_client tool ends up with a message.  It seems to use a more intricate mechanism than SSL_connect.)


-- 
Jordan Brown, Oracle Solaris

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

JordanBrown
Any thoughts here?

On 8/31/2018 6:14 PM, Jordan Brown wrote:

We're trying to nail down error reporting for TLS version mismatches, and we're seeing a couple of puzzling behaviors.

First, and most puzzling... assume these two command lines:

$ openssl s_server -cert 2018.08.31.a.pem -key 2018.08.31.a.key -no_tls1

$ openssl s_client -connect zel.us.oracle.com:4433 -tls1

That is, I have a server that won't accept TLSv1.0, and a client that will only accept TLSv1.0.

On the server side I see

1:error:14076102:SSL routines:SSL23_GET_CLIENT_HELLO:unsupported protocol:s23_srvr.c:605:

which makes perfect sense.  On the client side I see

4294956672:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:

which isn't as good, but is still sort of sensible.  But when I look at the packets exchanged, I see that the client sends a Client Hello, and the server responds with an ACK and then a FIN-ACK, with no data.  It just hangs up the phone.  This seems to violate RFC 5246 section E.1:  "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.".  Where's my protocol version alert?

Of course my real case does not involve the sample client and server - it involves my own clients and servers - but I seem to see the same behavior with several servers (notably including the Apache httpd).

This looks like it's the same as https://rt.openssl.org/Ticket/Display.html?id=2777 .  I'm using 1.0.2o.  (But I don't see anything relevant-looking in the 1.0.2p changes.)  I've seen similar behavior from 1.0.2o-fips.

Am I missing something here, or is this a server-side bug?


And then, on the client side...

SSL_connect returns zero.  Exactly how that failure differs from a less-than-zero error is not clear, but OK.  The docs say to call SSL_get_error().  SSL_get_error() returns 5, SSL_ERROR_SYSCALL.  (That seems a little strange, since I don't think there's any system call errors here.)  The docs say to consult the error queue and errno.  ERR_peek_last_error( ) returns zero.  Errno is zero.  It failed, but nobody will tell me why.

Am I missing something here, or is this a client library bug?


(I have not tracked down exactly how the s_client tool ends up with a message.  It seems to use a more intricate mechanism than SSL_connect.)


-- 
Jordan Brown, Oracle Solaris



-- 
Jordan Brown, Oracle Solaris

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

Kurt Roeckx
In reply to this post by JordanBrown
On Fri, Aug 31, 2018 at 06:14:25PM -0700, Jordan Brown wrote:

> We're trying to nail down error reporting for TLS version mismatches,
> and we're seeing a couple of puzzling behaviors.
>
> First, and most puzzling... assume these two command lines:
>
>     $ openssl s_server -cert 2018.08.31.a.pem -key 2018.08.31.a.key -no_tls1
>
>     $ openssl s_client -connect zel.us.oracle.com:4433 -tls1
>
> That is, I have a server that won't accept TLSv1.0, and a client that
> will only accept TLSv1.0.
>
> On the server side I see
>
>     1:error:14076102:SSL routines:SSL23_GET_CLIENT_HELLO:unsupported
>     protocol:s23_srvr.c:605:
>
> which makes perfect sense.  On the client side I see
>
>     4294956672:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl
>     handshake failure:s3_pkt.c:659:
>
> which isn't as good, but is still sort of sensible.  But when I look at
> the packets exchanged, I see that the client sends a Client Hello, and
> the server responds with an ACK and then a FIN-ACK, with no data.  It
> just hangs up the phone.  This seems to violate RFC 5246 section E.1: 
> "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.".  Where's my protocol version alert?
>
> Of course my real case does not involve the sample client and server -
> it involves my own clients and servers - but I seem to see the same
> behavior with several servers (notably including the Apache httpd).
>
> This looks like it's the same as
> https://rt.openssl.org/Ticket/Display.html?id=2777 .  I'm using 1.0.2o. 
> (But I don't see anything relevant-looking in the 1.0.2p changes.)  I've
> seen similar behavior from 1.0.2o-fips.

I can not reproduce this in 1.0.1, 1.0.2, 1.1.0 or 1.1.1. I
believe this was fixed in all branches. I've tried 1.0.2o too, and
I still get the alert back.

> And then, on the client side...
>
> SSL_connect returns zero.  Exactly how that failure differs from a
> less-than-zero error is not clear, but OK.  The docs say to call
> SSL_get_error().  SSL_get_error() returns 5, SSL_ERROR_SYSCALL.  (That
> seems a little strange, since I don't think there's any system call
> errors here.)  The docs say to consult the error queue and errno. 
> ERR_peek_last_error( ) returns zero.  Errno is zero.  It failed, but
> nobody will tell me why.

I assume that it returns SSL_ERROR_SYSCALL because something is
not properly setting an error, and SSL_get_error() returns
SSL_ERROR_SYSCALL when it doesn't know what else to return.
If the peer just closes the connection, you should have gotten
SSL_ERROR_SSL. I assume read() returned 0 because of EOF, which is
not an error for read() so it does not set errno, but OpenSSL
should have set an error instead.


Kurt

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

JordanBrown
On 9/10/2018 1:42 PM, Kurt Roeckx wrote:
I can not reproduce this in 1.0.1, 1.0.2, 1.1.0 or 1.1.1. I believe this was fixed in all branches. I've tried 1.0.2o too, and I still get the alert back.

Interesting.  My attempts were on Solaris x86[*].  I'll have to try other platforms.

[...later...]

With the Cygwin server (1.0.2n), I get different behavior.

The server says:
4294956672:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1500:SSL alert number 40
where you might recall the Solaris server said:

1:error:14076102:SSL routines:SSL23_GET_CLIENT_HELLO:unsupported protocol:s23_srvr.c:605:

The client (either Solaris or Cygwin) says:

1:error:1408F10B:SSL routines:SSL3_GET_<a class="moz-txt-link-freetext" href="RECORD:wrong">RECORD:wrong version number:s3_pkt.c:365:

which is perfect.

Time to go figure out why our OpenSSL server is misbehaving.
[*] As you might infer from my signature below, I work for Oracle in the Solaris group.  My immediate organization is primarily concerned with our Solaris-based storage products.  (That's not quite accurate, but you don't want to know about our org chart.)
-- 
Jordan Brown, Oracle Solaris

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

JordanBrown
In reply to this post by Kurt Roeckx
And of course I remember just after hitting Send:  Thanks!
-- 
Jordan Brown, Oracle Solaris

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

Viktor Dukhovni
In reply to this post by JordanBrown


> On Aug 31, 2018, at 9:14 PM, Jordan Brown <[hidden email]> wrote:
>
> We're trying to nail down error reporting for TLS version mismatches, and we're seeing a couple of puzzling behaviors.
>
> First, and most puzzling... assume these two command lines:
>
> $ openssl s_server -cert 2018.08.31.a.pem -key 2018.08.31.a.key -no_tls1

This disables TLS 1.0 on the server, and if SSL 3.0 is supported at compile time,
leaves the server willing to do SSL 3.0 or TLS 1.1 and up.

> $ openssl s_client -connect zel.us.oracle.com:4433 -tls1

This configures the client to do TLS 1.0 only via the version-specific
TLS1_client_method(), which DOES NOT support version negotiation.  It
is NOT equivalent in some subtle ways to:

  $ openssl s_client -connect zel.us.oracle.com:4433 -no_ssl3 -no_tls1_1 -no_tls1_2

That said, in either case the client sends "TLS 1.0" is its "maximum" protocol
version in its TLS client HELLO (the TLS 1.0 protocol does not support sending
a supported version list).

> That is, I have a server that won't accept TLSv1.0, and a client that will only accept TLSv1.0.

No, more precisely, you have a version-flexible server, that does not accept 1.0
and a *fixed-version* client that only supports 1.0.

What happens at that point depends on whether SSL 3.0 has been disabled on the server,
or not.  If SSL 3.0 is not disabled on the server (at compile time or by other means),
then seeing TLS 1.0 as the client's max version, the server will respond with SSL 3.0.
The client however, is not in a negotiating mood, and it will send a handshake failure
alert:

  SSL_connect:SSLv3 write client hello A
  SSL3 alert write:fatal:handshake failure
  SSL_connect:error in SSLv3 read server hello A
  140735512441800:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:365:

and on the server side you'll see:

  SSL_accept:before/accept initialization
  SSL_accept:SSLv3 read client hello A
  SSL_accept:SSLv3 write server hello A
  SSL_accept:SSLv3 write key exchange A
  SSL_accept:SSLv3 write server done A
  SSL_accept:SSLv3 flush data
  SSL_accept:SSLv3 read client certificate A
  SSL3 alert read:fatal:handshake failure
  SSL_accept:failed in SSLv3 read client key exchange A
  ERROR
  140735512441800:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1498:SSL alert number 40

If, on the other hand, you *also* disable SSL 3.0 on the server, then seeing
a maxim version or TLS 1.0 from the client, but with TLS 1.0 disabled the
server wants SSL 3.0, but that's also unavailable.  For better or worse,
OpenSSL is unable with respond with a TLS 1.0 alert (TLS 1.0 is off), nor
SSL 3.0, so it simply fails:

  SSL_accept:before/accept initialization
  SSL_accept:error in SSLv2/v3 read client hello A
  ERROR
  140735512441800:error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol:s23_srvr.c:643:
  shutting down SSL

The client's view of this is:

  SSL_connect:before/connect initialization
  SSL_connect:SSLv3 write client hello A
  SSL_connect:failed in SSLv3 read server hello A
  140735512441800:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:

You might argue that would should be able to send a TLS 1.0 fatal alert even
with TLS 1.0 disabled, but that's not how the OpenSSL 1.0.x code works.  It
does not select explicitly disabled protocols for sending alerts, nor does
it select protocol versions higher than the client's limit.

In OpenSSL 1.1.x, with its more modern rewritten state machine, the behaviour is closer to
what you expected.  Server reports:

  SSL_accept:before SSL initialization
  SSL_accept:before SSL initialization
  SSL3 alert write:fatal:protocol version
  SSL_accept:error in error
  ERROR
  140735512441728:error:14209102:SSL routines:tls_early_post_process_client_hello:unsupported protocol:../openssl/ssl/statem/statem_srvr.c:1655:

and client sees:

  SSL_connect:before SSL initialization
  SSL_connect:SSLv3/TLS write client hello
  SSL3 alert read:fatal:protocol version
  SSL_connect:error in error
  140735512441728:error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:../openssl/ssl/record/rec_layer_s3.c:1528:SSL alert number 70

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

JordanBrown
Thanks!

Now I need to wrap my head around what that all means.

It sounds like the protocol doesn't really have a version-independent way for the version negotiation to cleanly fail.  That's unfortunate.



--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

Viktor Dukhovni


> On Sep 11, 2018, at 12:33 PM, Jordan Brown <[hidden email]> wrote:
>
> Thanks!
>
> Now I need to wrap my head around what that all means.
>
> It sounds like the protocol doesn't really have a version-independent way for the version negotiation to cleanly fail.  That's unfortunate.

Well, once SSL3 is out of the picture (as in OpenSSL 1.1.x), TLS 1.0 and up
do all support the requisite alert, and the 1.1.x state machine seems to
handle this more along the lines that you expect.  The issue is that 1.0.2
is older and tries to stick to SSL 3.0 capabilities when talking to SSL 3.0
clients, ... so things get a bit messier.

Part of the confusion is also using a version inflexible method on the
client, that's rarely done. Instead of "s_client -tls1" it is wiser
to test with "s_client -no_ssl2 -no_ssl3 -no_tls1_1 -no_tls1_2".  That
is subtract the versions you don't want.  IIRC that still leaves you
"version flexible" even if only with a single version.

In OpenSSL 1.1.x all the "-no_some_version" options are superseded
by the min/max version options, which should be used instead.

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

JordanBrown
On 9/11/2018 9:46 AM, Viktor Dukhovni wrote:
Part of the confusion is also using a version inflexible method on the client, that's rarely done.

My test engineers like trying all the variations, including the ones nobody will ever use :-)

Instead of "s_client -tls1" it is wiser to test with "s_client -no_ssl2 -no_ssl3 -no_tls1_1 -no_tls1_2". That is subtract the versions you don't want. IIRC that still leaves you "version flexible" even if only with a single version.

In the application that's causing me trouble now, we start with SSLv23_method and then add SSL_OP_NO_SSLv2, SSL_OP_NO_SSLv3, and in this particular test case SSL_OP_NO_TLSv1_1 and SSL_OP_NO_TLSv1_2.

But how we construct the client configuration won't matter.  The client says "the highest I support is 1.0" and the server says (to itself) "the lowest I support is 1.1; I don't even know how to say 'no' so I'm just giving up".

The key piece that I was missing - I hadn't looked at and thought about the protocol enough - was that there's no version-independent way for the server to fail.  If the server supports only versions larger than the client supports, it has no way to say "no".  If the positions are reversed, the server counter-offers a version that the client then rejects as too old.

Thanks again.
-- 
Jordan Brown, Oracle Solaris

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

Viktor Dukhovni


> On Sep 11, 2018, at 1:17 PM, Jordan Brown <[hidden email]> wrote:
>
> The key piece that I was missing - I hadn't looked at and thought about the protocol enough - was that there's no version-independent way for the server to fail.  If the server supports only versions larger than the client supports, it has no way to say "no".  If the positions are reversed, the server counter-offers a version that the client then rejects as too old.

In OpenSSL 1.1.x, though the server might not support continuing with the client's
maximum version, it is willing to do so just long enough to send a fatal protocol
version mismatch alert.  It helps that SSL2/SSL3 are not supported, and TLS 1.0
and up support the alert.

Time to move to OpenSSL 1.1.x, it has many improvements, ...

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

Jakob Bohm-7
On 11/09/2018 19:34, Viktor Dukhovni wrote:

>
>> On Sep 11, 2018, at 1:17 PM, Jordan Brown <[hidden email]> wrote:
>>
>> The key piece that I was missing - I hadn't looked at and thought about the protocol enough - was that there's no version-independent way for the server to fail.  If the server supports only versions larger than the client supports, it has no way to say "no".  If the positions are reversed, the server counter-offers a version that the client then rejects as too old.
> In OpenSSL 1.1.x, though the server might not support continuing with the client's
> maximum version, it is willing to do so just long enough to send a fatal protocol
> version mismatch alert.  It helps that SSL2/SSL3 are not supported, and TLS 1.0
> and up support the alert.
>
> Time to move to OpenSSL 1.1.x, it has many improvements, ...
>
Clarification question, as I cannot match what you wrote above with
the changelog (NEWS) in the OpenSSL 1.1.1 tarball:

- Does OpenSSL 1.1.1 include SSL3.0 support or not?

Note that some real world clients are permanently stuck at SSL 3.0
due to the vendor refusing to release updates.


Enjoy

Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S.  https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark.  Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

Viktor Dukhovni


> On Sep 11, 2018, at 9:57 PM, Jakob Bohm <[hidden email]> wrote:
>
> Clarification question, as I cannot match what you wrote above with
> the changelog (NEWS) in the OpenSSL 1.1.1 tarball:
>
> - Does OpenSSL 1.1.1 include SSL3.0 support or not?

The code is there, but it is disabled in default builds.  You
need to run:

        ./Configure <target> enable-ssl3 ...

to get SSL 3.0 support.

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Version negotiation failure failure?

Viktor Dukhovni
In reply to this post by Viktor Dukhovni
Ah, yes.  Well that's why FIPS for OpenSSL is the main focus of the
next release, and presumably why Oracle is one of the sponsors... :-)

In the mean-time, yeah, you may have to support 1.0.2 for ~1 more year.

> On Sep 12, 2018, at 1:18 AM, Jordan Brown <[hidden email]> wrote:
>
> My understanding is that lack of FIPS-140 certification is a problem for us.

--
        Viktor.

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users