Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to access https web service from iOS

I am trying to access a web service which is available on https protocol. Initially I was getting following error:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802) errorAn SSL error has occurred and a secure connection to the server cannot be made.

I fixed it by adding following in my info.plist:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>xx.xx.xxx.xxx</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

But now I am getting following as html in response in connectionDidFinishLoading delegate method:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body>
</html>

I am using following to set up trust with server:

func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool{
    return true
}
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
    print("willSendRequestForAuthenticationChallenge")

    let protectionSpace:NSURLProtectionSpace = challenge.protectionSpace
    let sender: NSURLAuthenticationChallengeSender? = challenge.sender

    if(protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust){
        let trust:SecTrustRef = challenge.protectionSpace.serverTrust!
        let credential:NSURLCredential = NSURLCredential.init(forTrust: trust)
        sender?.useCredential(credential, forAuthenticationChallenge: challenge)
    }
    else{
        sender?.performDefaultHandlingForAuthenticationChallenge!(challenge)
    }
}

Update 1

The server logs are showing following error:

Hostname xx.xx.xxx.xx provided via SNI and hostname my_secured_host_name provided via HTTP are different

How can I add hostname in SNI?

Update 2

I have removed key to by pass http from info.plist as the service is already a https

Update 3

When I tried with openssl as

openssl s_client -showcerts -connect xx.xx.xxx.xxx:443

but I am getting following error:

CONNECTED(00000003) 8012:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.40.1/src/ssl/s23_lib.c:185

Update4: Changed Info.plist to following:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>xx.xx.xxx.xxx</key>
        <dict>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

Still getting following error:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802) errorAn SSL error has occurred and a secure connection to the server cannot be made.

like image 783
pankaj Avatar asked Oct 05 '15 04:10

pankaj


People also ask

How do you fix an SSL error has occurred and a secure connection to the server Cannot be made?

Clear your Browser's Cache and Cookies The SSL info of a website in your browser's cache and cookies might have expired, so if you clear both records, it could fix the issue for you.


1 Answers

I had the same problem as you, and I could solve it - mostly following what was already researched by you, posted here, and the background info provided by Steven Peterson.

I found that if I try connecting with the following settings, the -9802 error is gone:

NSAppTransportSecurity settings

Then it was just a matter of seeing which of those settings provides the solution. That's just a matter of finding out which one breaks it again if removed.

This may, of course, be a different one in your case.

Note that I do specify the domain by name, not by number, as pointed out by magma before. Also (at least in my case) no coding was involved in solving this problem.

Having solved it, I later learned that figuring out which settings to use can be automated:

/usr/bin/nscurl --ats-diagnostics --verbose https://your-domain.com
like image 166
ecotax Avatar answered Oct 24 '22 19:10

ecotax