Hi,
I have an IOS App connecting to a server (implemented in a web container) using NSURLSession. All communications are using HTTPs, the server is using TLSV1.2 with an accepted ciphers (see below for details).
I'm using IOS 9 beta3 (on iPad Air) and XCode 7 beta 3.
When starting the communication with the server I have always the same error:
2015-07-21 22:35:47.452 CellMonitoring[990:31106] Session download has failed : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo=0x7fa96d004cb0 {NSErrorFailingURLStringKey=https://localhost:8443/MyServer/App, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorFailingURLKey=https://localhost:8443/MyServer/App, _kCFStreamErrorCodeKey=-9802, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made.}
Below is the result of the openSSL command to display information about my server.
$ openssl s_client -host localhost -port 8443 -status
...
-----END CERTIFICATE-----
subject=XXXXX
issuer=YYYY
---
No client certificate CA names sent
---
SSL handshake has read 1465 bytes and written 510 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 55AEB2F8B99041A2B5975777FE793EB837AFB20BD7D0E00AA05A3F7ACB40BD38
Session-ID-ctx:
Master-Key: 6D77D7F9FAD54CFBD202806C927E188E0043306CB36F405FAA6F15E75F494BAA50F0B5E5D3BA2060D14BB14EE0EA239E
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1437512440
Timeout : 300 (sec)
Verify return code: 18 (self signed certificate)
---
closed
Below is the code I'm using for didReceiveChallenge, is there anything wrong or missing? I'm lost, I don't know how to progress :-(
#pragma mark - NSURLSessionDelegate Protocol
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
[RequestURLUtilities dumpChallenge:challenge];
if (challenge.protectionSpace != Nil) {
NSURLProtectionSpace *protection = challenge.protectionSpace;
SecTrustRef sslState = protection.serverTrust;
if (sslState == Nil) {
NSLog(@"%s Warning: empty serverTrust",__PRETTY_FUNCTION__);
}
if ([protection.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSLog(@"%s => NSURLAuthenticationMethodServerTrust", __PRETTY_FUNCTION__);
NSURLCredential* credential = [NSURLCredential credentialForTrust:sslState];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
} else {
NSLog(@"%s => Called for another challenge", __PRETTY_FUNCTION__);
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, NULL);
}
/
}
}
The App I'm developping is only for internal use in our Company and the server is also running in our private network. As a consequence we don't plan to get a certificate issued by a trusted CA.
Ah, that's a different story. In situations like this you should create a CA for your company, if you don't already have one, and have the server's certificate issued by a CA. You can then install the company CA's root certificate on the device as a system-trusted root (typically via MDM). Once you do that, ATS will trust your company CA's issued certificates, just like it trusts certificate's issued by any other CA whose root is installed on, or built in to, the system.
I tested this approach on a device here in my office, using a CA I maintain for my own personal server, and it worked just fine.
if I use an NSExceptionDomains the following it doesn't work, what is wrong?
…
192.168.***.YYY
I presume that the Info.plist doesn't contain "***" and "YYY" literally, but rather it has the actual numbers of your IP address.
Regardless, last I checked NSExceptionDomains is supposed to support IP addresses but does not due to a bug. I typically work around this by using the .local name.
Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"