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.