1

I want to validate my SSL certificate each time I run API calls. I've been following this guide:

http://artur.ejsmont.org/blog/content/how-to-properly-secure-remote-api-calls-from-php-application

This is my code:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://api-3t.sandbox.paypal.com/nvp");
curl_setopt($ch, CURLOPT_POSTFIELDS, ($apiCredentials . $nvpStr));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Returnerar resultatet istället för att skriva ut det

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, curlopt_cainfo, (dirname(__FILE__) . '/cacert.pem'));

$response = curl_exec($ch);

The problem is that my SSL cert is not validated at all - it seems the file cacert.pem isn't even checked! I have changed name of the file, deleted it, and I've even tried editing it by removing all certificates in the cacert.pem file that are from my certificate issuer. The API call is still run no matter what!

What might the problem be?

1 Answer 1

2

Quite simple :-)

First of all I got some weird errors when I run your script:

PHP Notice:  Use of undefined constant curlopt_cainfo - assumed 'curlopt_cainfo' in ...
PHP Warning:  curl_setopt() expects parameter 2 to be long, string given in ...

So I replaced with curlopt_cainfo with CURLOPT_CAINFO - that seems to get rid of them.

I added the following after curl_exec() call:

if (curl_errno($ch)) {
    echo 'Curl error: ' . curl_error($ch);
}

When I missed the cacert.pem or the path was invalid it showed:

Curl error: Problem with the SSL CA cert (path? access rights?)

After I tried to hack-in the certificate from the paypal site like this (do NOT do this on production environment):

openssl s_client -connect api-3t.sandbox.paypal.com:443 </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > cacert.pem

It complained again

Curl error: Peer certificate cannot be authenticated with known CA certificates

After properly supplying a certificate bundle from mozilla:

wget http://curl.haxx.se/ca/cacert.pem -O cacert.pem 

It works just fine :-)

I don't think you have to supply the CURLOPT_CAINFO option as curl comes bundled with the cacert.pem from mozilla and this should work out of the box with just CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST enabled.

2
  • Ah, at last someone who knows! I'm currently moving to a new server, and when it's done I'll try this out, thanks alot! Though, I don't understand this line: "wget curl.haxx.se/ca/cacert.pem -O cacert.pem". Can I do the same thing using PHP cURL as in my example above? Thanks! Aug 22, 2014 at 16:59
  • Hey Marcus, that is just to get a proper cacert.pem that contains world-wide trusted certification authorities (CA) - this particular one is an export from Mozilla. I got it from here: curl.haxx.se/docs/caextract.html But as I said earlier - curl should have this bundled, so you should not need the CURLOPT_CAINFO line at all. Feel free to ping me once you've migrated if you have troubles.
    – lukash
    Aug 22, 2014 at 17:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .