NSURLSession fails with error -1005

Hi,


we're developing an iOS 9 app that connects to a server with REST web services over HTTPS with two-way SSL.


I've implemented the delegate to handle authentication and can see in the log file that it's called with NSURLAuthenticationMethodClientCertificate first and with NSURLAuthenticationMethodServerTrust afterwards. So this seems to work fine.


But afterwards, the request fails with one of two errors:

- NSURLErrorDomain Code=-1005 "The network connection was lost." (_kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4)

- NSPOSIXErrorDomain Code=54 "Connection reset by peer"


We use the default NSURLSession configuration and add the following 3 elements:

- kCFNetworkProxiesHTTPEnable: NSNumber(int: 1)

- kCFNetworkProxiesHTTPProxy: proxy host name

- kCFNetworkProxiesHTTPPort: NSNumber(int: 8080)


Unfortunately, it's not possible to switch the server from HTTPS to HTTP for debugging.


Does anybody have an idea what could cause the two errors above, or how we could further analyze the problem?


Thank you,

Andreas

Accepted Reply

Hi Quinn,


thank you for your help. Contrary to my initial assumption, this was actually a TLS handshake problem. The server didn't accept the client certificate chain.

Initially, I had implemented the authentication handler for NSURLAuthenticationMethodClientCertificate like this:

...

var certRef: SecCertificate?

SecIdentityCopyCertificate(secIdentityRef, &certRef);

let certArray:NSMutableArray = NSMutableArray();

certArray.addObject(certRef!); // Causes client certificate to appear twice in the request


let credential = NSURLCredential(

identity: identityRef,

certificates: certArray as [AnyObject],

persistence: NSURLCredentialPersistence.ForSession)


It turns out that this causes the client certificate to be included twice, and the root certificate not at all.


Passing a nil certArray worked, as well as putting the root CA certificate in the array.


Greetings

Andreas

Replies

Most cases of

NSURLErrorNetworkConnectionLost
(-1005) are caused by the connection failing. That certainly seems to be the case where, where the underlying error is
ECONNRESET
(54), which is what you get when the remote peer closes out a connection from underneath you.

Given that this is HTTPS the best way to dig into this further is with a QA1887 CFNetwork Diagnostic Logging.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Quinn,


thank you for your help. Contrary to my initial assumption, this was actually a TLS handshake problem. The server didn't accept the client certificate chain.

Initially, I had implemented the authentication handler for NSURLAuthenticationMethodClientCertificate like this:

...

var certRef: SecCertificate?

SecIdentityCopyCertificate(secIdentityRef, &certRef);

let certArray:NSMutableArray = NSMutableArray();

certArray.addObject(certRef!); // Causes client certificate to appear twice in the request


let credential = NSURLCredential(

identity: identityRef,

certificates: certArray as [AnyObject],

persistence: NSURLCredentialPersistence.ForSession)


It turns out that this causes the client certificate to be included twice, and the root certificate not at all.


Passing a nil certArray worked, as well as putting the root CA certificate in the array.


Greetings

Andreas