tags:

views:

31

answers:

2

I got two certificate files from the provider, one in a .cer-format and one in a .p7b-format. I then converted the p7b-certificate to a p12-certificate. With this certificate I'm able to connect to the wsdl from my browser. Then I proceeded to convert that certificate to .pem-format, using some instructions I found on this site.

openssl pkcs12 -clcerts -nokeys -out test.pem -in mycert.p12
openssl pkcs12 -nocerts -out key.pem -in mycert.p12

then combing the cert with the key using the following command:

cat test.pem key.pem > cert.pem

Heres my construct for the web service class:

public function __construct() {
    $wsdl_url = 'https://url.to/web_service?wsdl';
    $pass = 'passphrase';
    $cert = 'cert.pem';

    try {
        $this->client = new SoapClient($wsdl_url, array('local_cert' => $cert, 'passphrase' => $pass));
    } catch(SoapFault $e) {
        print_r($e);
    }
}

And here is the error:

SSL operation failed with code 1. OpenSSL Error messages: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca in /var/www/html/..

Trying to verify the certificate using:

openssl verify cert.pem

gives me the following error:

error 20 at 0 depth lookup:unable to get local issuer certificate

I've also tried creating the .pem-certificate using the following openssl command:

openssl pkcs12 -in mycert.p12 -out mycert.pem

Verifying this gives me OK, but PHP gives me the following error:

Unable to set local cert chain file `mycert.pem'; Check that your cafile/capath settings include details of your certificate and its issuer

I'm assuming it should be possible to make it work somehow, as I am able to access the wsdl through my browser, by using the .p12-certificate. But I'm not able to locate a solution as to how I should proceed. Thanks in advance.

A: 

I think you have a few problems here. Firstly, I don't think your options for the local certificate are being used by the constructor for the SoapClient object. The options array does not support SSL config options. Secondly, given that the options you're supplying to the SoapClient are not being used Open SSL is complaining about the certificate on the remote host being a self certified certificate.

I think it should be possible to get around this but without playing with the code I can't be sure on all of the options. I think you need to create a custom stream context using stream_context_create() to set the SSL options you need (have a look at http://ca.php.net/stream_context_create and the context options for SSL). This can then be passed to the SoapClient object as the stream_context option in the config array. Using the stream_context you can set the various SSL options that you need and these will override the defaults.

I'm sorry I can't be more precise on the options you need to set. Hopefully playing around with the stream context will solve your issue.

Jeremy
A: 

I am thinking that it is unable to find the root certificate that issued the certificate that you were provided with.

Certificates are normally signed and issued by a signing authority, and your client needs to know the public key of the signing authority. If your certificate is a self signed certificate then it won't matter.

To check openssl x509 -text -noout -in key.pem

Check the output and look for Issuer. If the issuer is not the same as the CN of the certificate then you need a root certificate from the signing authority that provided your certificate.

You can normally grab it by using a browser to open your wsdl address and checking the certificate chain and exporting the root certificate from the hierarchy tab.

Where you save it in your situation I am not sure, but there will be something to point to a trust store of some type.

sweetfa