Ignoring a SSL certificate when using a webserver

Posted: July 23rd, 2008 | Author: | Filed under: Webserver | Tags: , , , , , , , | 4 Comments »

What happens when you try to connect to an HTTPS webserver which has an invalid SSL certificate? For example when the hostname of the website is not the same as the one in the SSL certificate.

With a browser (Safari or Firefox), you get an alert like the following:

If you try to connect to this webserver using NSURLConnection (Cocoa) or CFReadStream (Carbon), you get an error. In Cocoa, NSURLConnection fails with an error -1202 (NSURLErrorServerCertificateUntrusted). In Carbon, CFReadStreamRead returns -1, which means no data have been received.

The right way to fix this issue, is of course to create a new SSL certificate with the right hostname inside. But sometimes, it’s not your webserver and you don’t really care if the certificate is valid or not because you don’t send sensitive data. In that case, there is an easy way to just ignore the certificate.

With Carbon

If you are developing with Carbon, you can set some properties to the CFReadStream. To ignore the SSL certificate, you can simply set the property kCFStreamSSLValidatesCertificateChain of the CFReadStream to false. The following sample do a POST request: carbonSample

With Cocoa

NSURLRequest has a private method called setAllowsAnyHTTPSCertificate:forHost: which simply ignores the certificate.

The following sample do the same POST request as the Carbon version: cocoaSample

 

[Update]: As Uli Kusterer told me, you can have the same behavior as Safari. You can first try to connect to the HTTPS website without ignoring the certificate. If the certificate is invalid, you can present an alert like Safari to ask the user if he wants to ignore the certificate.


4 Comments on “Ignoring a SSL certificate when using a webserver”

  1. 1 Melloware said at 3:17 am on November 6th, 2008:

    I have tried this little trick for an app I have for the iPhone and it appears to work if the certificate is “Invalid” but if it is “Untrusted” Error Domain=NUSURLErrorDomain Code=-1202 UserInfo=0x12a7a0 “untrusted server certificate”

    I still get there error even with this trick. Any ideas?

  2. 2 byron said at 7:59 pm on October 2nd, 2009:

    yep, I get the same error as Melloware with a self signed cert (which I’m using for development) 🙁

  3. 3 Gordon Henriksen said at 5:31 pm on January 9th, 2010:

    There is a supported API for ignoring bad certificates, and it doesn’t require catching the NSError and restarting the NSURLRequest. Instead, add something like this to your NSURLConnection delegate:

    – (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
    }

    – (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    if ([trustedHosts containsObject:challenge.protectionSpace.host])
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
    }

    Note that connection:didReceiveAuthenticationChallenge: can send its message to challenge.sender (much) later, after presenting a dialog box to the user if necessary, etc.

  4. 4 Timac said at 6:02 pm on January 9th, 2010:

    Thanks for the comment about the delegate method ‘canAuthenticateAgainstProtectionSpace’. I didn’t know about it. This might be a good alternative to what I wrote, as long as you are developing for iPhone OS 3.0 (and later) or MacOSX 10.6 (and later). My solution has been testing on MacOSX 10.4 and later.


Leave a Reply