> From: owner-openssl-users On Behalf Of Ben Arnold
> Sent: Friday, November 08, 2013 10:45
<snip>
> I have tried using s_client and it fails with the same handshake failure.
Please
> see below.
> 
> 
> > Attaching a PCAP file of the traffic is much more useful than hex packet
> > dumps.
> 
> You're right of course, that is much more sensible.  I have attached two
pcap
> traces from s_connect, one success and one failure.
> 
> 
> > From: Dave Thompson
<snip: server cert>
> Yes, the server has a custom root cert that isn't installed on this
machine.  I
> am happy that the server cert is correct.
>
For testing that's okay, but I hope in real use you are verifying.
Otherwise an active attacker may be able to MITM your connections.

> > To OP: If you can try to reproduce with s_client default (which is
> > TLSv1.2 or less) and again specifying -tls1 (or -no_tls1_2 -no_tls1_1).
> > That might narrow it down pretty close.
> 
> I can reproduce the failure with s_client in the same manner.  It looks
(to me)
> like the server only asks for the client certificate once the GET command
has
> been issued, the initial negotiation doesn't ask for it.  I don't know the
TLS
> protocol so that might be normal.  Once I send the GET ... command it
tries to

Yes. More exactly, on the initial negotiation the server does not request
client auth 
(and thus openssl doesn't obtain and send it). After curl or s_client/you
sends 
the GET request, the server initiates renegotiation and does request client
auth 
except in the case using 1.0.1 where it fails before getting to that point.

Renegotiation is a standard capability of SSL/TLS and can be initiated by
either 
client or server. Whether and when it is used depends on the applications 
using SSL/TLS. *For HTTPS*, it is not uncommon for webservers to allow 
connection without client auth that can access "public" resources but
require 
renegotiation with client auth for "private" resources, and it certainly
appears 
this particular webserver is doing that.

> renegotiate but fails.  Looking at the output from s_client -state I see
this
> during the first negotiation...
> 
> ---
> No client certificate CA names sent
> ---
> SSL handshake has read 2884 bytes and written 639 bytes
> ---
> New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA
> Server public key is 2048 bit
> Secure Renegotiation IS NOT supported
> Compression: NONE
> Expansion: NONE
> 
> And then I send GET /directory HTTP/1.1 and see...
> 
> SSL_connect:SSL renegotiate ciphers
> SSL_connect:unknown state
> SSL_connect:failed in unknown state
> 16444:error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake
> failure:.\ssl\s3_pkt.c:1156:
> 
> 
> > From: Krzysztof Kwiatkowski
> >
> > Do you still see an error if you specify one cipher? f.e. AES256-SHA?
> 
> I do get an error when using AES256-SHA, in fact a much earlier error as
the
> server does not support that cipher, nor does it support AES-128-SHA.
> 
> However I took the idea and if I add -cipher "DES-CBC3-SHA" (as selected
by
> the server in the previous run) to s_connect then everything works OK, and
> if I add the same cipher selection to my program that that works too.
When I
> do specify DES-CBC3-SHA, s_client also reports
> 
> Secure Renegotiation IS supported
> 
> This sounds important to me! :)  Notice that the failure case reports
> renegotiation is NOT supported.
> 
To be exact it reports *secure* renegotiation is not supported. There 
are two slightly different renegotiation protocols, the original one 
(now usually called legacy or unsafe) which was found to be somewhat 
vulnerable to a MITM-splicing attack, and the updated RFC5746 one 
(sometimes called by the RFC#, but often just called "secure").
Client can detect from ServerHello whether the server supports RFC5746 
(or at least claims to) and the display tells you that. The client can't 
determine if "legacy" renegotiation is supported except by trying it, and 
even then can't be 100% certain because it could fail for another reason.

The ServerHello does indeed contain the secure-renegotiation extension 
in one pcap and not the other. Assuming there isn't some really weird 
logic on the server that supports 5746 only sometimes, this might be 
due to the (much) larger cipherlist -- OpenSSL puts ERI-SCSV at the end 
of the cipherlist, so if the server can only handle maybe 32 or 50 or so
entries 
in the cipherlist it might not "see" ERI in the default-ciphers case.

You could experiment with intermediate size cipherlists -- my suggestion 
of forcing -tls1 by itself takes you down from 80 to 52 (because it
implicitly 
disables the TLSv1.2-only SHA2 and GCM suites), or so does explicit -cipher 
DEFAULT:!TLSv1.2 . Removing more things you shouldn't want anyway 
goes lower e.g. DEFAULT:!TLSv1.2:!EXPORT:!LOW:!SRP:!kECDH should be 30.

Or you could try writing a Java SSL client, which allows you to position
ERI-SCSV 
anywhere you want in the list (i.e. end of 80, end of 40, 40th of 80, etc,
etc).

The renegotiation ClientHello is longer than the initial one because of the 
session-id and renegotiation-info extension, and as transmitted is longer 
yet because it is encrypted (and HMACed or GCMed) where the initial 
negotiation is not. But not very much longer.

> So the question now is, how come negotiation *is* supported when I
> manually specify DES-CBC3-SHA and *not* supported when I leave default
> ciphers, when the server ends up picking DES-CBC3-SHA anyway.
> 
> I have attached two pcap files, both captured using s_client - one with
the
> default ciphers and one with -cipher "DES_CBC3-SHA".  I notice that the
> Client Hello is slightly different, when using all ciphers there are two
extra
> extensions: ec_point_formats and elliptic_curves.  Whether or not this is
> relevant I have no idea, I imagine not as they are likely omitted because
DES
> isn't ECC.
> 
As well as the larger list of ciphersuites. You could try specifying a
cipherlist 
that includes one EC suite (or several but much less in total, like my
above). 
The two EC extensions are indeed omitted if *no* offered cipher is ECC.

(Aside: answering my own question earlier, in looking at ssl3_client_hello 
to check, there is a comment about renego offering our highest version, 
even if we know server is lower, because of the downgrade protection 
in the RSA premaster encryption for akRSA.)

> For now all the servers I need to talk to support DES-CBC3-SHA, this may
not
> always be the case.  Any idea how likely it is I will find a server that
doesn't?
> Or is there something else I can set to make renegotiation supported
without
> specifying the cipher.
> 
People who overreacted to BEAST but didn't overreact to the more recent 
RC4-bias repeated-data attacks from RHUL (or whose bosses did) may have 
disabled all CBC suites. But without TLSv1.2 GCM suites, the only cipher
algorithm 
left for those servers is RC4, and possibly relevant to you RC4 isn't
NIST-approved 
for TLS (or at all AFAIK) and I believe also not NSA.

If the problem is the length of the ClientHello and/or cipherlist -- as is 
consistent with but not conclusively proven by what you've seen so far,
and is somewhat similar to the fact that other servers have already been 
found to fail or hang *initial* negotiation when ClientHello >= 256 bytes 
(although this server did *not* fail there), just using a shorter cipherlist

should work. A few akRSA, one or two DHE-RSA and ECDHE-RSA because 
a server with RSA can still do akRSA unless KU prohibits, a few ECDHE-ECDSA 
and perhaps a few DHE-DSS -- maybe 20 total -- should handle any sane
server.

> Thanks for all your suggestions so far,
> Ben


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to