The question: How do we get Indy 10 to work with a web server that enforces the latest TLS 1.2 SSL Best Practices?
The Best Practices are documented by Microsoft: https://technet.microsoft.com/library/security/ms12-006 Essentially, a chunk of ciphers, used across multiple TLS versions, are considered insecure. Note, this kb is from mid 2013, well before poodle.
As a best practice, there are articles from the Delphi community related to the BEAST attack, that also propose disabling CBC based ciphers (http://www.atozedsoftware.com/Intraweb/Blog/20120905.EN.aspx)
Summary of Best Practices: The major breaches of SSL include the BEAST and the POODLE exploits. The scenario here is not edgy or narrow. This is a middle of the road "How to make a truly modern, reliable, SSL client based on Indy10+OpenSSL" topic. These breaches, in brief, indicate that SSL 2/3 is to be avoided, and TLS 1.0 is also considered vulnerable in many cases. Many CBC based ciphers are considered insecure.
I should add: This is not hypothetical. We had a penetration test consultant earlier in 2014 (pre-poodle) put on his report that our application servers (for our web app) be set to TLS 1.2 only and that all other SSL protocols be disabled. This consultant is part of a large web security firm, and they advise this in every review they do. I believe what they do is industry standard.
Indy 10 build: gsIdVersion = '10.6.0.5213';
In code, indy is set to: SSLOptions.SSLVersions := [ sslvSSLv23 ]
and openssl libs: 1.0.1.10 / 1.0.1J
Testing with a Win2012-R2 server, with ssl cert. We are progressively screwing down the SSL on the web server to conform to the most current SSL best practices.
We found an issue: Indy 10 is unable to connect when we enforce best practices AND TLS 1.2 only.
Browsers connect fine.
How we tested:
- Win2012-R2, Commercial SSL Cert.
- Using the Nartac Software "iis crypto" UI to modify the SSL config (schannel.dll config) on the Win2012 server (screen shots below)
Results:
When we implement just "Best Practices", Indy10 can connect fine. OpenSSL log info:
SSL status: "SSL negotiation finished successfully"
Cipher: name = AES256-SHA; description = AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1 ; bits = 256; version = TLSv1/SSLv3;
But when we take the above, AND we disable TLS 1.0 and TLS 1.1, the indy app can no longer connect. Open SSL logs:
SSL status: "SSLv2/v3 write client hello A"
SSL status: "SSLv2/v3 read server hello A" Socket Error # 10054 Connection reset by peer.
Here is the IIS Crypto config: (The Best Practices button below implements in one click what Microsoft recommends here: https://technet.microsoft.com/library/security/ms12-006 )
As Remy notes on comments to OP, the solution is to use the Indy 10 SSLIOHandler's CipherList property to set a list of ciphers.
Available ciphers:
https://www.openssl.org/docs/apps/ciphers.html
Some notes:
1) We were not able to get the wildcard examples on the openssl doc page above to work. e.g.: ALL:!ADH:@STRENGTH and the like, we could not make work.
2) The correct format is a list of ciphers, with a colon delimiter. E.g. AES128-SHA256:AES128-GCM-SHA256:ECDH-RSA-NULL-SHA
3) We found that providing a long list of ciphers (40 or more) actually gave us less connectivity to a variety of ssl servers. (It appears that some may be incompatible in the same list, or that openssl does an imperfect job of negotiating with the remote server.) Subsets of the list gave better results.
4) We have not found, so far, a solid, recommended, list.
5) We have been told that some ciphers should probably be avoided due to expensive (cpu intensive) nature of some of them. We have not investigated this area further at this time.
6) To future proof your app, allow a configuration or registry entry to modify the cipher list in the field. (Who knows what will be exploited and disabled next... Today SSL v3, tomorrow TLS 1.1...)