10

This worked fine for iOS 10.2 and below, but after upgrading to 10.3, when the simulator attempts to connect over HTTPS to the development server running on localhost, the Xcode console outputs the following errors:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
[] nw_coretls_callback_handshake_message_block_invoke_3 tls_handshake_continue: [-9807]

Printing out the error returned by the URLSessionDataTask shows:

Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x600000527080>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
    "<cert(0x7ff3e1867200) s: localhost i: localhost>"
), NSUnderlyingError=0x60800024e880 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x600000527080>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
    "<cert(0x7ff3e1867200) s: localhost i: localhost>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://localhost:3000/v1/login, NSErrorFailingURLStringKey=https://localhost:3000/v1/login, NSErrorClientCertificateStateKey=0}

Reference: Apple: Developer: Guides and Sample Code: Technical Note TN2232: HTTPS Server Trust Evaluation


To create a self-signed SSL certificate, I used the following commands:

openssl genrsa -aes256 -passout pass:x -out server.pass.key 2048
openssl rsa -passin pass:x -in server.pass.key -out server.key
rm server.pass.key
openssl req -new -sha256 -key server.key -out server.csr -subj /CN=localhost
openssl x509 -req -sha512 -days 365 -in server.csr -signkey server.key -out server.crt

Source: GitHub - seviu/iOS-SSL-localhost

ma11hew28
  • 121,420
  • 116
  • 450
  • 651

2 Answers2

13

After installing your self-signed SSL certificate (by dragging and dropping it) onto the iPhone Simulator, go to Settings > General > About > Certificate Trust Settings and enable full trust for your certificate.

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • I installed it, I see it in profiles, but Certificate Trust Settings is empty. What can I do now? – ReDetection May 12 '17 at 09:25
  • 2
    More over you need self-signed cert with `Basic Constraint` x509 extension with enabled `CA` option. Without it cert will be `Not verified` and Certificate Trust Settings will be empty. @ReDetection – Andrew Vyazovoy May 29 '17 at 16:39
  • Do you know why there is such a restriction? I haven't find any reasons nor documentation. This makes no sense to have a CA for me, I need a way to trust particular certificate for particular website, not a whole root authority. @AndrewVyazovoy – ReDetection May 30 '17 at 03:28
  • Actually, I made many experiments and find this correlation. `CA` option just mean that this cert can be used to verify other as I understand. This x509 extension is very easy to configure in Keychain Assistant when you create self-signed cert. @ReDetection – Andrew Vyazovoy May 30 '17 at 21:39
  • That's exactly what I'm trying to avoid. By trusting particular certificate I want to trust only that particular security exception and not all the certificates which can be signed/verified by this one. So tha's why I'm trying to figure out how to trust certificates without `CA` option. @AndrewVyazovoy – ReDetection Jun 01 '17 at 00:55
  • @AndrewVyazovoy Can you explain how we can update CA property ? Is it there [link](http://joxi.net/52aBw8VTG4l1VA.jpg) – Tikhonov Aleksandr Jun 02 '17 at 13:03
  • 1
    @TikhonovAlexander You can't "update" any field in certificate because it is signed. You can only recreate certificate with right fields. It is very easy to make in Keychain Access certificate assistant. Just set right checkboxes :) – Andrew Vyazovoy Jun 04 '17 at 00:01
  • @ReDetection You add self-signed cert as root cert. But root certs always intended to verify some other certs I suppose. Anyway, I find only this approach to add set-signed certs. If you find better workaround, write a comment, please. – Andrew Vyazovoy Jun 04 '17 at 00:09
0

I also had same problem , You have to implement didRecieveChallenge delegate method to handle SSl error

Add below ;one of code in didReceiveChallenge delegate method of URLSession delegate methods or URLConnnection deleagte method.

- (void)URLSession :( NSURLSession *)session didReceiveChallenge :( NSURLAuthenticationChallenge *)challenge completionHandler :( void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {   NSURLSessionAuthChallengeDisposition lDisposition = NSURLSessionAuthChallengeUseCredential;
NSURLCredential *credential = [[NSURLCredential alloc] init];


if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
    credential = [NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust];
    lDisposition = NSURLSessionAuthChallengeUseCredential;
}
completionHandler(lDisposition, credential);}
Kishor
  • 376
  • 4
  • 14