Misbehaving HTTPS Servers impair TLS 1.1 and TLS 1.2
Back in the summer of 2009, I blogged about Windows 7’s new support for TLS 1.1 and TLS 1.2. These new protocols are disabled by default, but can be enabled using Group Policy or the Advanced Tab of the Internet Control Panel:
Some adventurous Internet Explorer users have found that if they enable these new protocols, some secure sites will fail to load:
Upon encountering an error like this, a user might try to see what’s going wrong by enabling Fiddler’s HTTPS Decryption feature and re-visiting the site. When they do that, they find that the site starts working correctly.
What’s going on?
Fiddler is based on the .NET Framework’s SSLStream class, which only supports SSLv2, SSLv3, and TLS 1.0, and Fiddler only enables the latter two protocols by default. By running Fiddler, the user has effectively turned off outbound use of TLS v1.1 and TLS v1.2, and that remedies the connection problem.
To see what’s failing, you need to use a lower-level debugger like WireShark or Netmon. When you use Netmon, you’ll see the following sequence:
If you examine the “Encrypted Alert” from the server, you will see that it contains the byte sequence “02 46”, meaning Fatal Alert: Protocol Version.
The server isn’t supposed to behave this way—it’s instead expected to simply reply using the latest HTTPS protocol version it supports (e.g. "3.1” aka TLS 1.0). Now, had the server gracefully closed the connection at this point, it would be okay-- code in WinINET would fallback and retry the connection offering only TLS 1.0. WinINET includes code such that TLS1.1 & 1.2 fallback to TLS1.0, then fallback to SSL3 (if enabled) then SSL2 (if enabled). The downside to fallback is performance—the extra roundtrips required for the new lower-versioned handshake will usually result in a penalty amounting to tens or hundreds of milliseconds.
However, this server used a TCP/IP RST to abort the connection, which disables the fallback code in WinINET and causes the entire connection sequence to be abandoned, leaving the user with the “Internet Explorer cannot display the webpage” error message.
Because Fiddler doesn’t support the newest TLS protocol versions, it does not encounter this problem. However, there are even a few older HTTPS sites that cannot be viewed with Fiddler unless support for TLS 1.0 is disabled in Fiddler. That’s because Fiddler will not fallback from TLS 1.0 to SSL 3, while WinINET will do so (if SSL3 is enabled). If a server refuses a TLS 1.0 connection request from Fiddler, it’s treated as a fatal error. Only by disabling TLS 1.0 support in Fiddler (described here) can the sites’ traffic be successfully inspected by Fiddler.
Hopefully, buggy HTTPS servers will continue to wane in popularity and enable clients to successfully enable newer protocol versions with minimal compatibility impact.
Update: If the server negotiates a TLS1.2 connection with a Windows 7 or 8 schannel.dll-using client application, and it provides a certificate chain which uses the (weak) MD5 hash algorithm, the client will abort the connection (TCP/IP FIN) upon receipt of the certificate.