Closed Bug 946147 Opened 8 years ago Closed 8 years ago

TLS handshake fails for some broken servers after cipher suite order in client hello was changed in bug 936828

Categories

(NSS :: Libraries, defect, P1)

3.15.4
defect

Tracking

(Not tracked)

RESOLVED FIXED
3.15.4

People

(Reporter: briansmith, Assigned: briansmith)

References

()

Details

(Keywords: regression, Whiteboard: [See comment 7 for a list of sites known to be affected])

Attachments

(2 files, 1 obsolete file)

This is a follow-up from bug 942152.

With the new cipher suite order, Wireshark shows that the server chooses:

    Cipher Suite: TLS_RSA_WITH_DES_CBC_SHA (0x0009)

With the old cipher suite order, Wireshark shows that the server chooses:

    Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)

Note that Firefox doesn't enable TLS_RSA_WITH_DES_CBC_SHA, so ssl3_HandleServerHello fails, since the server never should have selected that one. So, this is an example of a cipher-suite-order-intolerant server.
Target Milestone: --- → 3.15.4
The new handshake ordering is (with the cipher suites that Firefox enables):

    0xC02B  TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    0xC02F  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    0xC009  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    0xC013  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
    0xC00A  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA

The old ordering had TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xC00a) before TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xC009), instead of after.

The problem appears to be that the server ignores the high-order byte of the cipher suite ID.
I verified my suspicion by disabling the TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA cipher suite in Firefox (security.ssl3.ecdhe_ecdsa_aes_128_sha=false in Firefox's about:config). When that cipher suite is disabled, the server chooses TLS_RSA_WITH_3DES_EDE_CBC_SHA. When that cipher suite is enabled, the server chooses TLS_RSA_WITH_DES_CBC_SHA and libssl fails with error SSL_ERROR_NO_CYPHER_OVERLAP.
The server supports the following cipher suites (according to my own testing, and verified with https://www.ssllabs.com/ssltest/analyze.html?d=avukat.uyap.gov.tr):

   TLS_RSA_WITH_RC4_128_MD5 (0x0004)
   TLS_RSA_WITH_RC4_128_SHA (0x0005)
   TLS_RSA_WITH_DES_CBC_SHA (0x0009)
   TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)

When we fall back to SSL 3.0, we end up dropping all the TLS_ECDHE_* cipher suites, which are the only ones that have a non-zero high byte. So, insecure fallback to SSL 3.0 works fine here. However, I'd like to stop doing the insecure fallback to SSL 3.0 in Firefox ASAP. So, either we'll need to whitelist this server, let this server break, or implement some workaround. Possible workarounds include:

(a) Move TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ahead of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA. But, I don't want to do this, because this hurts performance for some compliant servers.

(b) We can define a new dummy cipher suite, 0xFF0a or similar, and place it ahead of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA. These broken servers will choose TLS_RSA_WITH_3DES_EDE_CBC_SHA, and good servers will just ignore it.
Priority: P1 → P3
Target Milestone: 3.15.4 → 3.15.5
Preliminary research shows that the current (new) cipher suite order has compatibility issues with 10/10,000 sites on the Alexa top 100,000. It also shows that, for some reason, adding 0xff0a breaks at least one site: https://www.wine.com. So, adding 0xff0a is too risky to do in NSS 3.15.4.

Instead, let's move TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ahead of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, like it was before.
Target Milestone: 3.15.5 → 3.15.4
Status: NEW → ASSIGNED
Priority: P3 → P1
This attachment documents my thought process regarding the reordering of the cipher suite list to work around this problem. I verified that https://avukat.uyap.gov.tr/ works correctly with the new ordering.

In addition to the new ordering, applications that care about this issue should avoid enabling TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, and TLS_ECDH_ECDSA_WITH_RC4_128_SHA cipher suites, to minimize the chance of the buggy server choosing an export cipher suite.

In the table below, if the application enables the cipher suite in the left column, it should enable the cipher suite in the right column too, to maximize compatibility:

If you enable...                      | Then also enable...
--------------------------------------+-----------------------------------
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | TLS_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA  | TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA   | TLS_RSA_WITH_RC4_128_MD5
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA   | TLS_RSA_WITH_RC4_128_SHA

This information seems to be accurate as of the NSS 3.15.4. If/when we add new cipher suites with IDs larger than 0x00ff, this evaluation will have to be redone.
> If you enable...                      | Then also enable...
> --------------------------------------+-----------------------------------
> TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | TLS_RSA_WITH_AES_128_CBC_SHA
> TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA  | TLS_RSA_WITH_3DES_EDE_CBC_SHA
> TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA   | TLS_RSA_WITH_RC4_128_MD5
> TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA   | TLS_RSA_WITH_RC4_128_SHA

Actually, this table is over-simplified. For example, if you enable TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA then you must enable TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA and maybe TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, to get the correct second-order effects.
All of these servers will select TLS_RSA_WITH_DES_CBC_SHA even though TLS_RSA_WITH_DES_CBC_SHA isn't even offered, unless TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA appears before TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, in which case they will choose TLS_RSA_WITH_3DES_EDE_CBC_SHA.

Without this workaround, Firefox will do TLS intolerance fallback until SSL 3.0 (because we disable ECC cipher suites for SSL 3.0). With this workaround, Firefox will negotiate TLS 1.0. So, this is a change that improves security if the SSL 3.0 PRF is really less secure than the TLS 1.0 PRF.

In the list below, I have indicated the value of the "Server" header in the HTTP response of the home page. I was looking for a pattern, but there doesn't seem to be one. Thus, I suspect that this problem is caused by some load balancer or similar kind of device that does not inject its own "Server" header.

* https://catch.net.tw
  https://www.catch.net.tw     
  (Server: TWM)
 
* https://adalet.gov.tr
  https://www.adalet.gov.tr
  (Server: Microsoft-IIS/7.5, X-Powered-by: ASP.NET)
  
* https://www.uyap.gov.tr
  (Server: Microsoft-IIS/7.5, X-Powered-by: ASP.NET)
  
* https://globul.bg
  https://www.globul.bg
  (Server: Oracle Application Server/10g (10.1.2) Apache OracleAS-Web-Cache-10g/10.1.2.0.2)
  
* https://skysports.com
  (Server: IBM_HTTP_Server)

* https://avukat.uyap.gov.tr
  (Server: IBM_HTTP_Server)
Summary: TLS handshake with https://avukat.uyap.gov.tr fails after cipher suite order in client hello was changed in bug 936828 → TLS handshake fails for some broken servers after cipher suite order in client hello was changed in bug 936828
Whiteboard: [See comment 7 for a list of sites known to be affected]
Comment on attachment 8346448 [details] [diff] [review]
Move TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ahead of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA as a workaround

r=wtc.
Attachment #8346448 - Flags: review?(wtc) → review+
Comment on attachment 8346448 [details] [diff] [review]
Move TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ahead of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA as a workaround

Review of attachment 8346448 [details] [diff] [review]:
-----------------------------------------------------------------

::: lib/ssl/sslenum.c
@@ +45,5 @@
>      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
> +    /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA must appear before
> +     * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA to work around bug 946147.
> +     */
> +    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,

It would be nice to note the first four cipher suites, with the MSB zeroed,
look like
  TLS_KRB5_EXPORT_WITH_RC4_40_MD5 {0x00,0x2B }
  TLS_RSA_WITH_AES_128_CBC_SHA { 0x00,0x2F }
  TLS_RSA_WITH_3DES_EDE_CBC_SHA { 0x00,0x0A }
  TLS_RSA_WITH_DES_CBC_SHA { 0x00,0x09 }
to this broken server. The broken server only supports the third and
fourth ones and will select the third one.
https://hg.mozilla.org/projects/nss/rev/fda20ae77824

(In reply to Wan-Teh Chang from comment #10)
> It would be nice to note the first four cipher suites, with the MSB zeroed,
> look like
>   TLS_KRB5_EXPORT_WITH_RC4_40_MD5 {0x00,0x2B }
>   TLS_RSA_WITH_AES_128_CBC_SHA { 0x00,0x2F }
>   TLS_RSA_WITH_3DES_EDE_CBC_SHA { 0x00,0x0A }
>   TLS_RSA_WITH_DES_CBC_SHA { 0x00,0x09 }
> to this broken server. The broken server only supports the third and
> fourth ones and will select the third one.

I added this.
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
Version: trunk → 3.15.4
(In reply to Brian Smith (:briansmith, :bsmith, use NEEDINFO?) from comment #7)
> All of these servers will select TLS_RSA_WITH_DES_CBC_SHA even though
> TLS_RSA_WITH_DES_CBC_SHA isn't even offered, unless
> TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA appears before
> TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, in which case they will choose
> TLS_RSA_WITH_3DES_EDE_CBC_SHA.
> 
> Without this workaround, Firefox will do TLS intolerance fallback until SSL
> 3.0 (because we disable ECC cipher suites for SSL 3.0). With this
> workaround, Firefox will negotiate TLS 1.0. So, this is a change that
> improves security if the SSL 3.0 PRF is really less secure than the TLS 1.0
> PRF.
> 
> In the list below, I have indicated the value of the "Server" header in the
> HTTP response of the home page. I was looking for a pattern, but there
> doesn't seem to be one. Thus, I suspect that this problem is caused by some
> load balancer or similar kind of device that does not inject its own
> "Server" header.
> 
> * https://catch.net.tw
>   https://www.catch.net.tw     
>   (Server: TWM)
>  
> * https://adalet.gov.tr
>   https://www.adalet.gov.tr
>   (Server: Microsoft-IIS/7.5, X-Powered-by: ASP.NET)
>   
> * https://www.uyap.gov.tr
>   (Server: Microsoft-IIS/7.5, X-Powered-by: ASP.NET)
>   
> * https://globul.bg
>   https://www.globul.bg
>   (Server: Oracle Application Server/10g (10.1.2) Apache
> OracleAS-Web-Cache-10g/10.1.2.0.2)
>   
> * https://skysports.com
>   (Server: IBM_HTTP_Server)
> 
> * https://avukat.uyap.gov.tr
>   (Server: IBM_HTTP_Server)

Seems that most of the servers has added AES cipher suites, which likely means that this bug is fixed.
Except the Turkish government sites. Anyone has a contact?
Please file a TE bug.
Filed bug 1109373.
You need to log in before you can comment on or make changes to this bug.