A Windows 7 user of Fiddler encountered an interesting error this morning, and it reminded me of an interesting HTTPS compatibility problem we found in the Windows Vista timeframe.
The user is trying to visit https://www.atsenergo.ru with Fiddler running in HTTPS-decryption mode. Fiddler uses the SslStream class to communicate with upstream servers. As in IE itself, by default, the SSLv3 and TLSv1 protocols are enabled.
He finds that when he tries to use Fiddler to connect to this site, the following error is thrown in Fiddler:
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. —> System.ComponentModel.Win32Exception: The client and server cannot communicate, because they do not possess a common algorithm
— End of inner exception stack trace —
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at Fiddler.Pipe.Connect(Boolean bCreateConnectTunnel, IPEndPoint remoteEP, Boolean bSecureTheSocket, String sCertCN, String sClientCertificateFilename, String sPoolingKey)
at Fiddler.Pipe.Connect(IPEndPoint remoteEP, Boolean bSecureTheSocket, String sCertCN, String sClientCertificateFilename, String sPoolingKey)
Any time I encounter a problem with low-level HTTPS handshakes, my next stop is Netmon, which allows me to see what’s going out over the wire. The capture shows a standard TLS ClientHello, which offers up the standard set of Crypto algorithms, including TLSCipherSuites: TLS_RSA_WITH_AES_128_CBC_SHA. It then shows that the server responds a standard SSLv3 ServerHello, requesting SSLCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA.
At this point the connection fails with the exception message. Now, the exception text is clearly a bit misleading: the client and the server actually selected exactly the same cipher algorithm but there’s one problem: AES ciphers are not valid choices for SSLv3, although some servers will incorrectly try to use them.
We first encountered this problem during compat-testing of IE7 on Windows Vista back in 2006—because AES isn’t a supported cipher in SSLv3, SChannel rejects the choice of cipher. Today, that rejection leads to the exception in .NET’s SslStream class.
Now, in the WinHTTP and WinINET HTTPS stacks, we have special code to handle this problem—WinINET (and thus IE) simply falls back to SSLv3 when talking to the server.
To avoid performance-impacting fallback logic, server HTTPS implementations should be updated to properly choose a TLS ServerHello if they select an AES cipher, and if they use a SSLv3 ServerHello, they should choose a cipher defined for SSLv3.
Note that when the client (Fiddler, IE, etc) is running on Windows XP, this problem doesn’t occur, because SChannel does not support AES on that platform, so the client never offers AES when making the TLS connection.
Fiddler users running on Windows Vista or Windows 7 can workaround this problem in one of two ways: either manually disable use of AES by SChannel using Group Policy (generally a bad choice) or write a little bit of FiddlerScript to force Fiddler to use only SSLv3 upstream (which prevents sending of the TLS ClientHello that offers the AES cipher).
To update your FiddlerScript, click Rules > Customize Rules. Scroll down to the Main() function and add the following line within the function:
CONFIG.oAcceptedServerHTTPSProtocols = System.Security.Authentication.SslProtocols.Ssl3;
This will force Fiddler to only offer SSLv3 connections when connecting to secure servers, and that, in turn will resolve the problem.