Reputation: 2804
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:
The path is relative.
As you can see, I've supplied an absolute path.
The path is erroneous.
I've tried to var_dump(file_exists($certLocation));
, which gives me true
, so this is not the case.
The permissions on the file are incorrect.
I've set the permissions to 777
for debugging purposes. Error remains.
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
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
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