Default SSLLevel on Mac OS 10.9 onwards when using NSURLConnection - ssl

We have a legacy app which gets built against Mac 10.6 sdk. We are making use of NSURLMutableRequest and NSURLConnection to make web calls. Using Wireshark, I have noticed that on 10.9 - 10.11.2 all these calls get made on TLSv1. On 10.11.6 onwards(also 10.13 beta) these get made on TLSv1.2.
I changed the code to force TLSv1.2 using CFURLRequestSetSSLProperties(dlsym). I set kCFStreamSSLLevel to "kCFStreamSocketSecurityLevelTLSv1_2". After these I can see that calls get made on TLSv1.2 now.
From Apple documentation on kCFStreamSSLLevel :
By default, a stream’s security level is
kCFStreamSocketSecurityLevelNegotiatedSSL.
and from kCFStreamSocketSecurityLevelNegotiatedSSL :
Specifies that the highest level security protocol that can be
negotiated be set as the security protocol for a socket stream.
I know that TLSv1.2 is supported on 10.9. As a test, I set kCFStreamSSLLevel to
kCFStreamSocketSecurityLevelNegotiatedSSL and on 10.9 it still made calls to TLSv1.
I have 2 questions :
Why do calls gets made on TLSv1 for 10.9-10.11.2? Shouldn't they automatically choose highest version available i.e. TLSv1.2.
When using kCFStreamSocketSecurityLevelTLSv1_2, is there fallback to lower versions if server doesn't support TLSv1.2 or the call will simply fail?
I found this while checking :
kCFStreamSocketSecurityLevelNegotiatedSSL
Discussion: Stream
property value, for both set and copy operations. Indicates to use TLS
or SSL with fallback to lower versions. This is what HTTPS does, for
instance.
There's no such declaration for kCFStreamSocketSecurityLevelTLSv1_2 or even kCFStreamSocketSecurityLevelTLSv1. So will they fallback to lowers versions or not?

IIRC, the version-specific constants set a specific version, and it will not negotiate any other version. Negotiate, by contrast, allows it to negotiate any version that has not been blacklisted by Apple because of security concerns (e.g. SSLv3).
Thus, my recollection is that the general advice is to always use Negotiate on the client side unless you are required to use a specific version to enable support for a host that is incapable of using newer versions of SSL/TLS or for servers that don't support negotiation correctly, and then to always set your servers to accept only the most recent version (or slightly older, if needed to support older clients).
The advantage to that approach is that your client code won't have to change as Apple adds new versions and deprecates old ones, and the server is presumably under your direct control, so you can change it at any time without forcing your users to download a software update.

Related

Simple understanding of https protocol

Out of curiosity, can someone help explain to me what will theoretically happen if a uri of protocol https (TLS 1.1) is accessed on a primitive browser that predates TLS 1.1? E.g. a primitive feature phone with GPRS connectivity.
If your server only support TLS1.1 and a browser without TLS1.1 try to connect, the connection will fail.
Usually servers supports TLS1.0, 1.1 and 1.2 : Modern browsers can use the 1.2 version, but older ones can still connect on the 1.0 version.
https://ssllabs.com can help you see it (it tests websites to determine which browser can connect to it and the level of security of the connexion)

How to force WebLogic 10.3.2.0 to use TLS v1.0 minimum?

Having trouble with chrome v 4x.xx and WebLogic not automatically handshaking via tls 1.0 minimum. While calling a RESTful service from JavaScript front end I keep getting net::ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION since Google have dropped support for SSL V3.0. I have tried adding the flag forcing this to JAVA_OPTIONS and on another occasion to the starting arguments for WebLogic, despite knowing these only become suported in 10.3.6. Is there another way?
So it turns out WebLogic 10.3.2.0 has a bug in it. When the client makes contact with the server for the first time it tells the server which SSL/TLS certificate version it supports - UP TO. The latest Chrome I believe supports TLS v1.2, so this is the only information sent to WebLogic. WebLogic has problems recognising that 1.2 is greater than 1.0, (which is the highest version available on WebLogic 10.3.2.0 (AFAIK, it is on ours) and should therefore be trusted, so terminates the connection.
source - https://productforums.google.com/forum/#!topic/chrome/iwX2PbNGk8E

Does disabling SSLv2 and SSLv3 have any breaking changes on the end user?

We have clients who can be using anything, WindowsXP,Vista,Linux....
Currently our systems support SSLV2 and SSLV3.But, we are planning to disable both SSLV2 and SSLV3 in windows server 2008R2 in favour of TLS 1.2.
Will it have any breaking changes with the end user?I'm worried that If I disable SSLV3 ( and SSLV2) , some of the clients who use windowsXP(for example) might not be able to access my web service.
PS: Tried to find a similar question in stackoverflow, didn't find any. So, posting this as a question. :)
This is one of the scenarios where you will NOT be able to support old clients using insecure protocols and expect to have decent security.
If you have not enabled TLS 1.2 yet, do so.
Some clients do not support TLS 1.2 (e.g., older Android versions). You may need to support TLS 1.0 and 1.1 in addition to 1.2. While not ideal, it is definitely better than supporting SSL 2.0 and 3.0.
Post an announcement indicating that your web service is being upgraded to meet minimum security requirements and set a date for retiring insecure protocols.
Optionally, check your server metrics to see what protocols/ ciphers are used. Since you haven't mentioned your web server, I'm assuming it is IIS, in which case this is not easy[1][2].
Retire SSL 2.0 and SSL 3.0. There will be a few clients who will not be able to connect. Plan to have an answer ready for them. If you have clients running XP and using IE6, they have bigger issues than not being able to access your web service.
While you are at it, run your TLS configuration through an online
scanner like SSL Labs to ensure you fix any other issues.

Can I detect the SSL version that a browser supports?

I would like to display a message to customers who's browser's highest level of encryption is SSLv3. Is it possible for me to target browser settings of SSLv3 and lower? Client or Server code? We will be allowing lower versions of SSL to use our site during a certain grace period. During this grace period, we would like to display a message only to those users that have browser settings of SSL3 or lower.
Not easily. The browser's supported SSL versions are not detectable until the SSL handshake is in progress, and even then only if the browser uses an SSLv2 handshake to allow dynamic version negotiation. If an unsupported version were detected, you would not be able to send a message back since the handshake failed and the connection would be closed before you could send any message. However, SSL itself has an error packet that gets sent during handshaking, and it can specify a version mismatch error.
The best you can do in your own code is support all SSL versions on the server side, let the client complete a handshake normally, and then detect which version was actually used and send back a message if the SSL version is too low.
Or, you could simply enable TLSv1 or higher only, and simply refuse to let older clients connect at all. They just would not get a nice error message unless the browser decided to detect the SSL version mismatch error and display its own pretty message about it.
Firstly, nowadays, you can generally forget about clients that don't support at least SSLv3. SSLv3 has been widely available for many years.
The TLS Client Hello message, sent when the connection is initiated by the browser, should contain the highest TLS version it supports:
client_version
The version of the TLS protocol by which the client wishes to
communicate during this session. This SHOULD be the latest
(highest valued) version supported by the client. For this
version of the specification, the version will be 3.3 (see
Appendix E for details about backward compatibility).
Appendix E is of course worth looking at.
(The Client Hello message will also contain the list of cipher suites the client supports, which is possibly relevant for the general idea of your question.)
Of course, this specification is just a "SHOULD", so a client supporting TLS 1.2 could still send a Client Hello for TLS 1.1, but what would be the point? By doing so it would have no chance ever to use TLS 1.2 anyway. It could be a preference box that is turned off, but that would effectively make it a client that doesn't support the highest version anyway. (If you want anything more subtle, you'd need to build a database of known user agents, which will be partly unreliable, and for which you'd need to analyse the full user agent string to know everything possible about the platform.)
Now, how to convey the content of the Client Hello message to your application is another matter, and depends very much on which SSL/TLS stack you use. It might not even be directly possible without modifying that SSL/TLS library or the server you're using.
This being said, you can generally get the negotiated TLS version during the current session quite easily. Since that version is the "lower of that suggested by the client in the client hello and the highest supported by the server" (i.e. "min(max(client), max(server))"). If your server supports SSLv3, TLS 1.0, TLS 1.1 and TLS 1.2, and since the latest version is TLS 1.2 anyway, what you'll get during your current connection will also be the max currently supported by the client. As long as your server supports the latest version, you should be able to know what the client supports at best from any live connection.
If you're behind Apache HTTP server's mod_ssl, you should be able to get that from the SSL_PROTOCOL environment variable. You should also be able to get the protocol from the SSLSession in Java.
(If you are willing to write a more bespoke service, you could pass further details like the cipher suites more directly to your application, like this service from Qualys SSL Labs does, although I'm not sure if it's meant to be widely available or just a test service.)
I'd have to agree with Remy about it being a bit challenging.
However, a good starting point may be to retrieve some SSL (certificate) information.
Something similar to this:
X509Certificate certChain[] =
(X509Certificate[]) req.getAttribute("javax.net.ssl.peer_certificates");
Another way of getting more information is to retrieve the cipher_suite attribute (similar to the code snippet above).
javax.net.ssl.cipher_suite
I hope this (at least) gets you closer.
Good luck.

Find out SSL version (V2 or V3)

How can one tell if the SSL communication between a client and a server is SSLv2 or SSLv3?
On the SSL protocol level, the second byte of the header contains the major version of the protocol, which is 3 for SSLv3/TLS, presumably 2 for SSLv2. Note that the client sends the highest version it supports in its ClientHello message, and the server responds with the version it chose (which may be lower) in the ServerHello message.
Of course, you should work with an API that allows you to query the version without getting down to the protocol level.