Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C/Cocoa: How do I accept a bad server certificate?

Using NSURLRequest, I am trying to access a web site that has an expired certificate. When I send the request, my connection:didFailWithError delegate method is invoked with the following info:

-1203, NSURLErrorDomain, bad server certificate

My searches have only turned up one solution: a hidden class method in NSURLRequest:

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:myHost];

However, I don't want to use private APIs in a production app for obvious reasons.

Any suggestions on what to do? Do I need to use CFNetwork APIs, and if so, two questions:

  • Any sample code I can use to get started? I haven't found any online.
  • If I use CFNetwork for this, do I have to ditch NSURL entirely?

EDIT:

iPhone OS 3.0 introduced a supported method for doing this. More details here: How to use NSURLConnection to connect with SSL for an untrusted cert?

like image 630
Mike McMaster Avatar asked Aug 18 '08 21:08

Mike McMaster


1 Answers

The supported way of doing this requires using CFNetwork. You have to do is attach a kCFStreamPropertySSLSettings to the stream that specifies kCFStreamSSLValidatesCertificateChain == kCFBooleanFalse. Below is some quick code that does it, minus checking for valid results add cleaning up. Once you have done this You can use CFReadStreamRead() to get the data.

CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("http://www.apple.com"), NULL);
CFHTTPMessageRef myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), myURL, kCFHTTPVersion1_1);
CFReadStreamRef myStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);
CFMutableDictionaryRef myDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(myDict, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
CFReadStreamSetProperty(myStream, kCFStreamPropertySSLSettings, myDict);    
CFReadStreamOpen(myStream);
like image 52
Louis Gerbarg Avatar answered Feb 12 '23 15:02

Louis Gerbarg