Closed Bug 359484 Opened 18 years ago Closed 17 years ago

FireFox 2 tries to negotiate ECC cipher suites using ssl2 client hello

Categories

(NSS :: Libraries, defect, P1)

3.11.3
defect

Tracking

(Not tracked)

RESOLVED FIXED
3.11.4

People

(Reporter: nelson, Assigned: nelson)

Details

(Whiteboard: [hot fix in 3.11.4])

Attachments

(1 file)

The RFC for ECC cipher suites requires clients that support fewer than the 
full set of 25 named curves to NOT negotiate ECC cipher suites UNLESS they
send the "support curves" client hello extension, telling the server which
of the 25 named curves they support.  

The ssltap output shown below is purportedly from a connection between a
FF 2.0 RTM browser and a Sun server.  It shows the browser sending a 
client hello in SSL2 format, trying to negotiate SSL 3.0, but including
many ECC cipher suites in the list of cipher suites.  

I added code to libssl to disable all the ECC cipher suites when sending an
SSL2 style client hello.  See 
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ssl/sslcon.c&rev=1.28.2.5&root=/cvsroot#3123
and 
http://bonsai.mozilla.org/cvsview2.cgi?command=DIFF&subdir=mozilla%2Fsecurity%2Fnss%2Flib%2Fssl&file=sslcon.c&rev1=1.28.2.3&rev2=1.28.2.5&whitespace_mode=show&diff_mode=context

Did that code not go into FF 2.0?  
Did FF 2.0 get built with NSS_ECC_MORE_THAN_SUITE_B defined?

Connected to xxxx:8080
--> [
alloclen = 111 bytes
(111 bytes of 111)
 [Fri Nov  3 14:23:46 2006] [ssl2]  ClientHelloV2 {
           version = {0x03, 0x00}
           cipher-specs-length = 84 (0x54)
           sid-length = 0 (0x00)
           challenge-length = 16 (0x10)
           cipher-suites = {
                (0x00c00a) TLS/ECDHE-ECDSA/AES256-CBC/SHA
                (0x00c014) TLS/ECDHE-RSA/AES256-CBC/SHA
                (0x000039) TLS/DHE-RSA/AES256-CBC/SHA
                (0x000038) TLS/DHE-DSS/AES256-CBC/SHA
                (0x00c00f) TLS/ECDH-RSA/AES256-CBC/SHA
                (0x00c005) TLS/ECDH-ECDSA/AES256-CBC/SHA
                (0x000035) TLS/RSA/AES256-CBC/SHA
                (0x00c007) TLS/ECDHE-ECDSA/RC4-128/SHA
                (0x00c009) TLS/ECDHE-ECDSA/AES128-CBC/SHA
                (0x00c011) TLS/ECDHE-RSA/RC4-128/SHA
                (0x00c013) TLS/ECDHE-RSA/AES128-CBC/SHA
                (0x000033) TLS/DHE-RSA/AES128-CBC/SHA
                (0x000032) TLS/DHE-DSS/AES128-CBC/SHA
                (0x00c00c) TLS/ECDH-RSA/RC4-128/SHA
                (0x00c00e) TLS/ECDH-RSA/AES128-CBC/SHA
                (0x00c002) TLS/ECDH-ECDSA/RC4-128/SHA
                (0x00c004) TLS/ECDH-ECDSA/AES128-CBC/SHA
                (0x000004) SSL3/RSA/RC4-128/MD5
                (0x000005) SSL3/RSA/RC4-128/SHA
                (0x00002f) TLS/RSA/AES128-CBC/SHA
                (0x00c008) TLS/ECDHE-ECDSA/3DES-EDE-CBC/SHA
                (0x00c012) TLS/ECDHE-RSA/3DES-EDE-CBC/SHA
                (0x000016) SSL3/DHE-RSA/3DES192EDE-CBC/SHA
                (0x000013) SSL3/DHE-DSS/DES192EDE3CBC/SHA
                (0x00c00d) TLS/ECDH-RSA/3DES-EDE-CBC/SHA
                (0x00c003) TLS/ECDH-ECDSA/3DES-EDE-CBC/SHA
                (0x00feff) SSL3/RSA-FIPS/3DESEDE-CBC/SHA
                (0x00000a) SSL3/RSA/3DES192EDE-CBC/SHA
                }
           session-id = { }
           challenge = { 0x54bc 0x134f 0x38f3 0x8026 0xba5c 0xdc5c 0x71ed 0xdf30 }
}
]
<-- [
(742 bytes of 737)
SSLRecord { [Fri Nov  3 14:23:46 2006]
   type    = 22 (handshake)
   version = { 3,0 }
   length  = 737 (0x2e1)
   handshake {
      type = 2 (server_hello)
      length = 70 (0x000046)
         ServerHello {
            server_version = {3, 0}
            random = {...}
            session ID = {
                length = 32
                contents = {..}
            }
            cipher_suite = (0xc014) TLS/ECDHE-RSA/AES256-CBC/SHA
            compression method = 00
         }
      type = 11 (certificate)
      length = 468 (0x0001d4)
         CertificateChain {
            chainlength = 465 (0x01d1)
            Certificate {
               size = 462 (0x01ce)
               data = { file 'cert.002' }
            }
         }
      type = 12 (server_key_exchange)
      length = 183 (0x0000b7)
      type = 14 (server_hello_done)
      length = 0 (0x000000)
   }
}
]
--> [
(7 bytes of 2)
SSLRecord { [Fri Nov  3 14:23:46 2006]
   type    = 21 (alert)
   version = { 3,0 }
   length  = 2 (0x2)
   fatal: handshake_failure
}
]

I am leaving this "unconfirmed" until I am SURE that this was experienced
with FF 2 RTM and not one of the Beta or RC versions.
If it can be shown that this occurs with FF2 RTM, this is a P1 bug, 
worthy of an immediate fix in the next FF2 update.
Priority: -- → P1
The browser with which this problem was seen identifies itself with this 
User Agent string:

Firefox 2.0 (Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR; rv:1.8.1) Gecko/20061010 Firefox/2.0)

I cannot tell from that if it is the RTM version or not.  October 10?
It is a version localized for Brazil.  
The previous bug for this issue was bug 341707
(In reply to comment #0)
> I added code to libssl to disable all the ECC cipher suites when sending an
> SSL2 style client hello.  See 
> http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ssl/sslcon.c&rev=1.28.2.5&root=/cvsroot#3123
> and 
> http://bonsai.mozilla.org/cvsview2.cgi?command=DIFF&subdir=mozilla%2Fsecurity%2Fnss%2Flib%2Fssl&file=sslcon.c&rev1=1.28.2.3&rev2=1.28.2.5&whitespace_mode=show&diff_mode=context
> 
> Did that code not go into FF 2.0?  

The current 1.8 branch contains that snippet, so AFAIK: yes

> Did FF 2.0 get built with NSS_ECC_MORE_THAN_SUITE_B defined?

The PSM Makefiles do not define it, nor do the master mozilla makefiles, so AFAIK: no


(In reply to comment #2)
> The browser with which this problem was seen identifies itself with this 
> User Agent string:
> 
> Firefox 2.0 (Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR; rv:1.8.1)
> Gecko/20061010 Firefox/2.0)
> 
> I cannot tell from that if it is the RTM version or not.  October 10?
> It is a version localized for Brazil.  

The string "rv:1.8.1" indicates it was built from the branch for Firefox 2.0. The build date 20061010 indicates that it should contain it, because according to Bonsai your change went in to that branch 2006-08-04.


Have you attempted to ssltap a connection using an official FF 2 release, disabling SSL 3 and TLS, enabling SSL 2, to any ecc enabled server, and see what happens? That will force FF to use a v2 hello.
Kai Engert has confirmed that the build downloaded from 
http://www.mozilla.com/products/download.html?product=firefox-2.0&os=win&lang=pt-BR
as of this date has the problem.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Kai wrote to me:

> I am able to reproduce that bug on linux, too
> it indeed is related to TLS intolerance retry

Question: what happened to make PSM think this server was TLS intolerant?
The fact that the server attempted to negotiate an ECC cipher suite pretty
clearly indicates that it is NOT TLS intolerant.

Your first attempt to reproduce this on Linux produced a PASS result.
What was different about this second test that produced a FAIL result?

Kai, thanks for your testing on this. 
Clearly one lesson from this is that we must also do TLS intolerance 
testing against servers that are NOT TLS intolerant.  

> when PSM suspects TLS intolerance, it will make the following calls:
> SSL_OptionSet(fd, SSL_ENABLE_TLS, PR_FALSE) and 
> SSL_OptionSet(fd, SSL_V2_COMPATIBLE_HELLO, PR_TRUE) 
> - after that libssl sends a v2 hello with ECC

That all seems to be exactly as it should be.

OK, I've found something that seems to explain how/why we send the 
bad list of cipher suites.  But it raises a bunch of other questions. :(

Function ssl2_BeginClientHandshake, which formats and sends the SSL2 
format client hello, contains TWO calls to ssl2_ConstructCipherSpecs(),
the function that constructs the list of supported & enabled cipher suites
to be sent in the client hello.  See sslcon.c at lines 3006 and 3128.
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ssl/sslcon.c&rev=1.28.2.5&root=/cvsroot#3006
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ssl/sslcon.c&rev=1.28.2.5&root=/cvsroot#3128
The second of those two calls is a no-op.

The code I added at line 3124, to disable the ECC cipher suites for an SSL2
client hello before constructing the cipher suite list, is also a no-op, 
because the list has already been constructed.  This is a failure of the 
fix for bug 341707.

Taking...
Assignee: rrelyea → nelson
(In reply to comment #6)
> Question: what happened to make PSM think this server was TLS intolerant?

I do not know what had caused PSM to assume PSM intolerance on that server your customer talked to.

I know that meanwhile we have a lot of cases where we conclude TLS intolerance. We have several error codes during the connection. And recently we had noticed a new class of broken servers, that simply stalled after a v3 hello with hello extensions. Because of that we had recently changed PSM to conclude TLS intolerance after a timeout of about 20 seconds.

Going back to the test results I had reported to you today. 

Because this bug is about v2 hellos, and because I know that we enable v2 hellos on TLS intolerance, I suspected this bug report might have to do with that.

In order to simplify the testing, I made a small source code change on my local machine, and made PSM always assume a TLS intolerance server and go straight to the fallback scenario.

After that I just connected to the first ecc server that came to my mind, and I immediately saw the reported behaviour.


> The fact that the server attempted to negotiate an ECC cipher suite pretty
> clearly indicates that it is NOT TLS intolerant.

Maybe the browser ran into that timeout scenario because of some temporary network issues?


> Your first attempt to reproduce this on Linux produced a PASS result.
> What was different about this second test that produced a FAIL result?

As explained above, I could reproduce the reported FAIL result after forcing PSM to assume TLS intolerance, without having attempted the initial connecting with TLS.


> Kai, thanks for your testing on this. 
> Clearly one lesson from this is that we must also do TLS intolerance 
> testing against servers that are NOT TLS intolerant.  

Not sure what you are suggesting here.
Attached patch Hot fixSplinter Review
This obvious patch (which Nelson also outlined at the end of
comment 6) makes the original patch work.  I assume Nelson
is working on a proper fix, so I call this a hot fix.
Comment on attachment 245262 [details] [diff] [review]
Hot fix

Nelson, is this hot fix acceptable for NSS 3.11.4?
When will you be able to write a patch for this bug?
Attachment #245262 - Flags: review?(nelson)
Comment on attachment 245262 [details] [diff] [review]
Hot fix

This is obviously not the final fix, as Wan-Teh has already written, but for a "hot fix", I think this will do the job.
Attachment #245262 - Flags: review?(nelson) → review+
(In reply to comment #10)
> [...] for a "hot fix", I think this will do the job.  

But I haven't tested it.  I call upon the folks who build and use the
"Basic ECC" builds to test this thoroughly before committing it, and 
having mozilla take this fix.
I tested Wan-Teh's patch and when forcing the TLS intolerance retry, the SSL v2 hello no longer seems to include any ECC ciphers, I got:

Connected to ecc.fedora.redhat.com:443
--> [
alloclen = 63 bytes
(63 bytes of 63)
[Fri Nov 10 21:04:43 2006] [ssl2]  ClientHelloV2 {
          version = {0x03, 0x00}
          cipher-specs-length = 36 (0x24)
          sid-length = 0 (0x00)
          challenge-length = 16 (0x10)
          cipher-suites = {
               (0x000039) TLS/DHE-RSA/AES256-CBC/SHA
               (0x000038) TLS/DHE-DSS/AES256-CBC/SHA
               (0x000035) TLS/RSA/AES256-CBC/SHA
               (0x000033) TLS/DHE-RSA/AES128-CBC/SHA
               (0x000032) TLS/DHE-DSS/AES128-CBC/SHA
               (0x000004) SSL3/RSA/RC4-128/MD5
               (0x000005) SSL3/RSA/RC4-128/SHA
               (0x00002f) TLS/RSA/AES128-CBC/SHA
               (0x000016) SSL3/DHE-RSA/3DES192EDE-CBC/SHA
               (0x000013) SSL3/DHE-DSS/DES192EDE3CBC/SHA
               (0x00feff) SSL3/RSA-FIPS/3DESEDE-CBC/SHA
               (0x00000a) SSL3/RSA/3DES192EDE-CBC/SHA
               }
          session-id = { }
          challenge = { 0x2141 0xd5b3 0x68e6 0x7a40 0x1ebe 0xed10 0xd91e 0xd236 }
}
]
<-- [

I haven't done additional testing yet.
Comment on attachment 245262 [details] [diff] [review]
Hot fix

Alexei, please review this hot fix for NSS 3.11.4.  Thanks.
Attachment #245262 - Flags: superreview?(alexei.volkov)
Attachment #245262 - Flags: superreview?(alexei.volkov) → superreview+
I checked in the hot fix on the NSS trunk (NSS 3.12) and the
NSS_3_11_BRANCH (NSS 3.11.4).

Checking in sslcon.c;
/cvsroot/mozilla/security/nss/lib/ssl/sslcon.c,v  <--  sslcon.c
new revision: 1.34; previous revision: 1.33
done

Checking in sslcon.c;
/cvsroot/mozilla/security/nss/lib/ssl/sslcon.c,v  <--  sslcon.c
new revision: 1.28.2.6; previous revision: 1.28.2.5
done
Whiteboard: [hot fix in 3.11.4]
A work around for FF2 users who find they can no longer connect to certain
SSL/TLS servers is to 
- go to the "about:config" page, 
- filter on the term "ecdhe", and then 
- find any entries with a value of "true" and toggle them to say false.
I consider this bug to have been fixed by the "hot patch" in NSS 3.11.4.
Yes, the SSL2 client path is suboptimal.  But IMO we don't care about 
optimal performance in SSL2, so this is good enough.
Status: NEW → RESOLVED
Closed: 17 years ago
Resolution: --- → FIXED
Target Milestone: --- → 3.11.4
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: