2
votes

First of all, I know there are a ton of similar questions, but none that I've seen seems to address my setup (nor any solution I found works). So bear with me...

  • My server host name is an IP address, not a domain name (i.e., URL looks like: https://XXX.YYY.ZZZ.WWW:9443/etc...).
  • My server has a real certificate (i.e., not self signed).
  • My app's plist entry NSAppTransportSecurity dictionary is empty (no exceptions whatsoever - factory settings ATS).
  • This is production code and I can not disable ATS (nor do I think I could, given that exceptions only work with explicit domain names, not IP addresses).

(Testing on iOS 9, deployment target is iOS 8.x)

I am getting this error when I try to connect:

CFNetwork SSLHandshake failed (-9806) NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9806) Error: An SSL error has occurred and a secure connection to the server cannot be made.

(Device and Simulator)

I tried to command line tool nscurl described here. I get:

  • Default ATS Secure Connection: CFNetwork SSLHandshake failed (-9806)
  • Allowing Arbitrary Loads: NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) ("The certificate for this server is invalid. You might be connecting to a server that is pretending to be “XXX.YYY.ZZZ.WWW” which could put your confidential information at risk.")
  • Configuring TLS exceptions for XXX.YYY.ZZZ.WWW: (TLS 1.2, 1.1 and 1.0) CFNetwork SSLHandshake failed (-9806)

  • Disabling Perfect Forward Secrecy: CFNetwork SSLHandshake failed (-9801)

  • Disabling Perfect Forward Secrecy and Allowing Insecure HTTP: CFNetwork SSLHandshake failed (-9801)

  • TLSv1.2 with PFS disabled: CFNetwork SSLHandshake failed (-9801)

  • TLSv1.1 with PFS disabled: CFNetwork SSLHandshake failed (-9801)

  • TLSv1.0 with PFS disabled: NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

  • TLSv1.2 with PFS disabled and insecure HTTP allowed: CFNetwork SSLHandshake failed (-9801)

...you get the drill.

I am having checked which TLS version the server supports (that is the biggest suspect, as far as I've researched), but perhaps there is something else I need to fix/check on the client side?

1
have you tried handling authentication challenges in connection delegates ? - vishnuvarthan
I have implemented all delegate methods of NSURLSession. I set breakpoints in URLSession:task:didReceiveChallenge:completionHandler: and URLSession:didReceiveChallenge:completionHandler:, but they aren't hit. - Nicolas Miari
I'm suspecting the server's TLS version might be too low, but I can't tell yet. Perhaps I'm missing something else... - Nicolas Miari
have you tried this? - Rok Jarc
@rokjarc have you read my question? I can not disable ATS. I need to solve this for production code, and transmit confidential customer data; there is no temporary workaround. Also, my server does not have a domain name (only an IP address), and ATS only allows for domain exceptions. - Nicolas Miari

1 Answers

2
votes

I think you need to inspect the cert on your server. You should be able to use the openssl client to investigate your certificate and get your server's ssl config:

openssl s_client  -connect XXX.YYY.ZZZ.WWW:9443 

You should get some details about the cert

SSL-Session: Protocol : TLSv1 Cipher : AES256-SHA Session-ID: // Session-ID-ctx: Master-Key: // Key-Arg : None Start Time: 1449693038 Timeout : 300 (sec) Verify return code: 0 (ok)

Or, you can use a website like symantec to query the cert and see if you have met the requirements of TLS1.2, a strong enough key, and forward secrecy.

Also, you could try turning on CFNetwork Diagnostic Logging. Edit the Xcode scheme and add the CFNETWORK_DIAGNOSTICS environment variable. Set the logging level to 3 which is the most verbose:

The Xcode console shows the location of the log file:

CFNetwork diagnostics log file created at: /private/var/mobile/Containers/
Data/Application/A3421F00-451A-CD70-1B82-B163D1A3BB0F/Library/Logs/
CrashReporter/CFNetwork_com.sample.app_118.nwlrb.log

You could look into those logs to see if there is any more information as to why the network calls are failing.