Ios – Use a self-signed ssl certificate in an iphone app

asihttprequestiosnsurlrequestsslssl-certificate

I apologize in advance for the long-winded question. I'm having trouble with a self-signed SSL cert and I want to document everything I've tried so far.

I'm working on an app that communicates with a REST service. The test server uses a self-signed ssl certificate that I can install on my computer without issue. It's a .p12 file that requires a password to install. Without this certificate installed, all requests to the server return a 403.

The .p12 installs three items in the Keychain, a "Root certificate authority", a "test user" certificate that's issued by the "Root certificate authority", and a private key that's associated with the "test user" cert.

I've installed this certificate on my iPad by emailing myself the .p12 file. I tapped on the attachment, input the password, and I can now access the site in Safari. Unfortunately, because of application sandboxing, this isn't enough to get my app to communicate with the REST service.

I'm using ASIHTTPRequest for all of the communication with the REST service from my app. Each request is a subclass of ASIHTTPRequest. The first thing I found I had to do was call [self setValidatesSecureCertificate:NO]; so that it would even attempt the SSL connection to the server. If that's all I do, I get 403 error codes back from the service.

Now I can't seem to figure out how to get the request to use the certificate. I've tried exporting the three items as separate .cer file, including them in the project and adding them to the request using the code below:

NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"cert" ofType:@"cer"]];
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef)data);
...
[self setClientCertificates:[NSArray arrayWithObjects:(id)cert, ..., nil]];

While the code executes without issue using this approach, I still get the 403 error.

I've even tried including the .p12 file in my application and importing it using the same code. This fails because SecCertificateCreateWithData returns nil.

I admit I don't really know what I'm doing here. This is all a little over my head and any help anyone could give me would be greatly appreciated.

Best Answer

OK, I figured it out. I was sort of barking up the wrong tree.

The most important information I found was in Apple's documentation for Certificate, Key, and Trust Services Programming Guide, in particular, the "Tasks for iOS" page. That detailed how to extract the security identity from the .p12 file and how to add a trust exception.

The last piece of the puzzle was in ASIHTTPRequest's documentation on Client Certificate Support. By using the identity I extracted directly from the p12 file, I was able to pass that on to the request and get everything authenticated properly.

I hope this helps anyone else that has to implement a similar feature.