PHP: cURL SSL Verification

Published:

While trying to figure out of PayPal Payment Data Transfers I came over an issue that caused my cURL requests to fail.

These were the cURL options I used:

curl_setopt_array($request, array
(
    CURLOPT_URL => 'https://www.sandbox.paypal.com/cgi-bin/webscr',
    CURLOPT_POST => TRUE,
    CURLOPT_POSTFIELDS => http_build_query(array
    (
        'cmd' => '_notify-synch',
        'tx' => $tx,
        'at' => $your_pdt_identity_token,
    )),
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_HEADER => FALSE
));

Worked great on my web host, but locally didn't get any response. Turned out I was getting an error, SSL certificate problem: unable to get local issuer certificate, and here are two ways to fix it.

Globally via php.ini

  1. Go to curl.haxx.se/docs/caextract.html
  2. Download the cacert.pem and put it somwhere, for example C:\wamp\cacert.pem
  3. Edit the curl.cainfo property in the curl section:
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = C:\wamp\cacert.pem
  1. Restart the web server

Locally via curl option

  1. Go to curl.haxx.se/docs/caextract.html
  2. Download the cacert.pem and put it for example next to your script.
  3. Set the CURLTOPT_SSL_VERIFYPEER and CURLOPT_CAINFO options when you're executing a curl request
curl_setopt_array($request, array
(
    // Other options...
    CURLOPT_SSL_VERIFYPEER => TRUE, // Verify peers
    CURLOPT_CAINFO => 'cacert.pem' // Path to file with certificates
));

Why?

Since we are using the HTTPS protocol we need to somehow verify the one we are talking to. Your browser does this by checking their certificate against several built-in certificate stores from trusted certificate suppliers, like for example VeriSign.

cURL does this verification automatically as well, except on my local machine PHP wasn't configured with a default store to use.

Solution was as you can read above, to find one, and let PHP know about it, either through php.ini or through curl options.

Voila!