Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP load failed (kCFStreamErrorDomainSSL, -9813) in Cordova app

I've created an iOS app using Cordova 3.2 and jquery mobile 1.3. I use jquery ajax to send requests to a RESTfull service to retrieve/update information.

I have a number of test devices, various iPhones, with various different iOS versions. On an iPhone 4S, running iOS 7 I receive the following error when any ajax request is sent:

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

This only happens on this device, on another iPhone 4S, also running iOS 7, it works absolutely fine, as it does on all of the other test devices I'm using.

I've read that this indicates the certificate is invalid in someway, that being the case, can this be ignored and why would affect on one device?

Can anyone suggest why this might be happening and what could be different about the device that would prevent it from working only on one of my devices. Thanks

like image 436
Martin Cassidy Avatar asked Jan 09 '14 16:01

Martin Cassidy


4 Answers

I had a similar issue, but in my case, across all devices this used to happen and only during an ajax call with https.

If that is your case, adding the below code at the end of appDelegate.m file will mitigate your issue.

@implementation NSURLRequest(DataController) 
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host 
{ 
return YES; 
} 
@end 

But i do doubt that if it is working in other devices, the solution i have given, might not be effective. But do give it a try.

like image 81
Markiv Avatar answered Oct 23 '22 14:10

Markiv


If it's working on some devices and not others, there's some difference in the certificate validation parameters for those devices. Here are some things to look at:

  1. Do the happy devices have some root certificate that the unhappy devices don't? Particularly if they are running different iOS versions, they may have different lists of trusted certificates as well. Try going to Settings > General > About and compare the numbers for "Trust Store" at the very bottom. See more info here.
  2. Did you manually accept some intermediate certificate (used to sign this certificate) on the happy devices at some point in the past?*
  3. Is the date/time wrong on the unhappy device? If it's set to a time after the certificate expiry date or before the certificate issue date, it will reject it. I'm always shooting myself in the foot with this one!

If you access your endpoint URL in the browser on the unhappy device, what error does it give you? (Note: obviously your server will give you some error as well because you aren't requesting with the right headers and params. I'm talking about Safari itself, though - it should give a more detailed message about what (it thinks) is wrong with the certificate.)

*Edited to correct something I misremembered: you do not have the option to accept the leaf certificate if you go to the URL in Safari, you only have the option to accept intermediate certificates if you attempt to load them directly.

like image 12
Arkaaito Avatar answered Oct 23 '22 15:10

Arkaaito


The Swift version of Markivs answer (taken from here):

extension NSURLRequest {
    static func allowsAnyHTTPSCertificateForHost(host: String) -> Bool {
        return true
    }
}
like image 2
Chris Avatar answered Oct 23 '22 13:10

Chris


Xcode 7.3 Swift 2.2

To get this to work I had to do 3 things:

  1. I had to add Chris's answer^ to the bottom of the AppDelegate.swift after the closing } for the class
  2. then modify Info.plist using this answer https://stackoverflow.com/a/32701693
    • you can get additional information at Apple Developer
  3. Make sure you set a domain name for the server instead of an IP Address
like image 2
Brewster Avatar answered Oct 23 '22 13:10

Brewster