Search code examples
iossslnsurlsessionapp-transport-security

Can Not Connect to Server Using HTTPS


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?


Solution

  • 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.