Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I accept a self-signed SSL certificate using iOS 7's NSURLSession

I have the following code (swift implementation):

func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool
{
    return protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
}

func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge)
{
    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
    {

        if challenge.protectionSpace.host == "myDomain"
        {
            let credentials = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
            challenge.sender.useCredential(credentials, forAuthenticationChallenge: challenge)
        }
    }

    challenge.sender.continueWithoutCredentialForAuthenticationChallenge(challenge)

}

It works perfectly in iOS 8.x, but does not work iOS 7.x In iOS 7.x I have error:

NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)

Any idea? thank you!!!

like image 834
Carlos Cardoso Avatar asked Jun 09 '15 17:06

Carlos Cardoso


People also ask

How add self-signed certificate to trusted IOS?

If you want to turn on SSL/TLS trust for that certificate, go to Settings > General > About > Certificate Trust Settings. Under "Enable full trust for root certificates," turn on trust for the certificate. Apple recommends deploying certificates via Apple Configurator or Mobile Device Management (MDM).

How do I accept a self-signed certificate?

Navigate to the site with the cert you want to trust, and click through the usual warnings for untrusted certificates. In the address bar, right click on the red warning triangle and "Not secure" message and, from the resulting menu, select "Certificate" to show the certificate.

How do I import a self-signed SSL certificate?

Import the self-signed certificate to the client Windows computer. On the Windows computer, start MMC (mmc.exe). Add the Certificates snap-in for the computer account and manage certificates for the local computer. Import the self-signed certificate into Trusted Root Certification Authorities > Certificates.


1 Answers

Both connection:canAuthenticateAgainstProtectionSpace: and connection:didReceiveAuthenticationChallenge: are deprecated in iOS 8 anyway so you should use other methods.

What I am using in my projects is a delegate method of NSURLSessionDelegate. Adhere to that protocol then add this method:

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
    completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust))
}

Then, when you use initialize NSURLSession with delegate set to self. For example:

var session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue())

Then use that session instance to call dataTaskWithRequest method on:

var task = session.dataTaskWithRequest(request){
    (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
    if error != nil {
        callback("", error.localizedDescription)
    } else {
        var result = NSString(data: data, encoding:
            NSASCIIStringEncoding)!
    }
}
task.resume()

Complete working example can be found here.

For security reasons, if you use a self-signed certificate I recommend also implementing public key pinning (https://gist.github.com/edwardmp/df8517aa9f1752e73353)

like image 89
edwardmp Avatar answered Oct 19 '22 02:10

edwardmp