I am attempting to make POST requests to a secure server in my app, without a certificate. When I make a request I'm getting these errors in the console:
2018-04-24 16:14:22.942030-0400 TIC TCP Conn Failed [8:0x60000017c440]: 1:54 Err(54)
2018-04-24 16:14:22.942779-0400 Task <1E09E1AE-CE51-48C4-9A56-F3738B8FD68F>.<1> HTTP load failed (error code: -1005 [1:54])
2018-04-24 16:14:22.943219-0400 [93037:8075678] Task <1E09E1AE-CE51-48C4-9A56-F3738B8FD68F>.<1> finished with error - code: -1005
In URLSession:didReceiveChallenge
I'm not validating the certificate; I'm simply calling continueWithoutCredentialForAuthenticationChallenge
.
I have my domain set as an exception for ATS in Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>mydomain.net</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
I can't find any documentation on what Err(54)
and error code: -1005
mean, so I'm running into a roadblock while troubleshooting. It may also be worth mentioning that I have to connect my Mac to my VPN to ping this server, and that I'm running this in my simulator.
I'm hoping to hear some suggestions for what might be going wrong and how to fix.
I found that the issue was with how I was handling
URLSession:didReceiveChallenge
. I was only callingcontinueWithoutCredentialForAuthenticationChallenge
. What I did to get it to work was to call thecompletionHandler
with a credential:SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; ASSERT(nil != serverTrust); NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
You need to understand what your ATS settings are allowing your app to do.
NSAllowsArbitraryLoads
being set to true allows you connect to any server over HTTP. So feel free to attempt to load data from any URL with thehttp
scheme.Your exception domain setting (assuming that your "mydomain.net" is a placeholder for the actual value) will allow you to connect to any subdomain (because
NSIncludesSubdomains
is true) of "mydomain.net" using:NSTemporaryExceptionAllowsInsecureHTTPLoads
set to true)NSThirdPartyExceptionRequiresForwardSecrecy
to true)First, verify you can connect to the URL you are attempting to connect to from Safari on the device in question (in this case, the simulator). Safari does not enforce ATS requirements, so you can see if it is ATS related. If you cannot access the URL, it is related to the connection. This could be server being unreachable, or it could be a problem with the certificate for a secure connection. If this is the problem, you can probably get rid of any ATS exceptions you added trying to resolve the issue.
If you can connect to the resource, try to verify what ATS requirements are not being met so you can add the appropriate exceptions. In the Terminal on your Mac, run the following to get a report on the server's compliance with ATS rules:
This will tell you if the server doesn't support forward secrecy, or if the TLS version is too low. Then you can add the specific ATS exceptions for that domain.
I still believe that there is another problem, as ATS errors in the log are usually very clear. Your error seems like a general connectivity problem. You mention having your Mac connected to a VPN. Does your VPN require you to use an HTTP/HTTPS proxy? If so, I have had problems with the simulator trying to use the mac's proxy when the proxy requires certain types of authentication. If your http proxy requires authentication, you might try standing up something like Charles Proxy as an intermediary. i.e. setup Charles Proxy to authenticate to your company's proxy, then point the Mac / simulator to use the local Charles proxy which should be configured to not need authentication.