views:

768

answers:

3

I need to make some code to talk to a SOAP web service. Unfortunately I'm unable to get a connection to the service as it requires a SSL connection encrypted with a special certificate. I've been given a pk12 certificate which when installed into my keychain allows me to access the SOAP service manually via Safari, but I'm unable to get a connection from the Cocoa web services stuff :( Does anybody have any ideas on what I might have to do to get this to work?

A: 

I've hit similar problems. Is this a self-signed certificate? If so, you may find all you need to do is alter the trust settings on this certificate.

There is another workaround, where you say that this site should ignore trust settings, but this leaves you open to man-in-the-middle attacks. There is another thread on SO about this topic:

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

Matthew Schinckel
I've already set the trust settings on the certificate to "Always Trust" but that didn't seem to help me. It is almost as though the WS functions are not looking at the keychain :(
Daniel
Yep, I hit this problem too. I had to use the technique in the linked post, with a slight addition - I needed to do an NSURLRequest first before I did my WS stuff.Then it worked as expected.
Matthew Schinckel
I wasn't able to get the WSInvocation stuff to work, and in the end I had to build the SOAP envelope and perform a HTTP post manually, but Matthew pointed me in the right direction.
Daniel
A: 

Typically, you must present the certificate as part of your code. For instance, in C#, you need to specify the certificate like this:

using System.Security.Cryptography.X509Certificates;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //some code creating your soap client

        string cert_file = "C:\\prf_res.pem"; //You'll probably use the PEM format here, not the .p12 format
        X509Certificate cert = new X509Certificate(cert_file);
        soap_client.ClientCertificates.Add(cert);

        //now you're set!

In PHP, it would be:

   $cert = "myCert.pem"; //notice it's in PEM format. 

   $client = new SoapClient($wsdl, array('local_cert' => $cert));

To make a PEM file out of a .p12, you can use:

OpenSSL> pkcs12 -in myCert.p12 -out myCert.pem -nodes -clcerts

Nick R.