PHP cURL certificate error

I'm attempting to add a custom cer-certificate to my PHP cURL request, but I keep getting this error:

error setting certificate verify locations:
  CAfile: /path/to/my/cert.cer
  CApath: none

All I've found about this error is that:

  1. The path is relative.
    As you can see, I've supplied an absolute path.

  2. The path is erroneous.
    I've tried to var_dump(file_exists($certLocation));, which gives me true, so this is not the case.

  3. The permissions on the file are incorrect.
    I've set the permissions to 777 for debugging purposes. Error remains.

  4. The path to the file doesn't have +x-permissions somewhere in the chain.
    I've set this as well, ensuring that the entire path from root has +x-permissions, and still no luck.

I'm at a loss here, having tried everything I can find, and fact is, I don't even understand what the error actually means. What is a verify location? All I can understand is that there's an error with loading the file.

Any light shed on this is greatly appreciated. See code example below.

Thanks.

Code I use:

<?php

$oCurl = curl_init($this->baseUrl);
curl_setopt($oCurl, CURLOPT_FAILONERROR, 1);
curl_setopt($oCurl, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($oCurl, CURLOPT_CONNECTTIMEOUT, $this->connectionTimeout);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($oCurl, CURLOPT_POST, 1);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($oCurl, CURLOPT_CAINFO, "/tmp/cert.cer");

Error:

error setting certificate verify locations:
  CAfile: /tmp/cert.cer
  CApath: none

Upvotes: 1

Views: 5880

Answers (2)

godvsdeity
godvsdeity

Reputation: 969

CURLOPT_CAINFO is used in conjunction with CURLOPT_SSL_VERIFYPEER

CURLOPT_CAINFO should be set to a CA or CA-bundle in PEM format. I managed to track the curl code which triggers this error and this is what I found:

in curl/openssl.c:

if(!SSL_CTX_load_verify_locations(connssl->ctx,
                                   data->set.str[STRING_SSL_CAFILE],
                                   data->set.str[STRING_SSL_CAPATH])) {
  if(data->set.ssl.verifypeer) {
    /* Fail if we insist on successfully verifying the server. */
    failf(data, "error setting certificate verify locations:\n"
          "  CAfile: %s\n  CApath: %s",
          data->set.str[STRING_SSL_CAFILE]?
          data->set.str[STRING_SSL_CAFILE]: "none",
          data->set.str[STRING_SSL_CAPATH]?
          data->set.str[STRING_SSL_CAPATH] : "none");
    return CURLE_SSL_CACERT_BADFILE;
  }
  ...

Apparently the call on SSL_CTX_load_verify_locations returns 0 and combined with the fact of having CURLOPT_SSL_VERIFYPEER set to 1 it triggers the error.

SSL_CTX_load_verify_locations is a function from openssl library, and according to the documentation(SSL_CTX_load_verify_locations documentation), the following statements should be taken into consideration:

"If CAfile is not NULL, it points to a file of CA certificates in PEM format."

"The CAfile is processed on execution of the SSL_CTX_load_verify_locations() function."

"0 - The operation failed because CAfile and CApath are NULL or the processing at one of the locations specified failed." under RETURN VALUES section


You could try to convert your cer to a pem using the following command:

openssl x509 -in /tmp/cert.cer -inform der -outform pem -out /tmp/cert.pem

but I can't guarantee that this will work, because I'm not sure if you even have a proper CA or CA bundle file.

Upvotes: 2

Pedro Lobito
Pedro Lobito

Reputation: 99031

If your PHP installation doesn't have an up-to-date CA root certificate bundle, download the one at the curl website and save it on your server:

http://curl.haxx.se/docs/caextract.html

Then set a path to it in your php.ini file, e.g. on Windows:

curl.cainfo=c:\php\cacert.pem

NOTE:
Turning off CURLOPT_SSL_VERIFYPEER allows man in the middle (MITM) attacks, which you don't want!


SRC1 - https://stackoverflow.com/a/14064903/797495
SRC2 - http://php.net/manual/en/function.curl-setopt.php#110457

Upvotes: 3

Related Questions