Reputation: 9518
Good day!
I've REST API which is accessible via SSL (https://). I'd like to put correct cert (or cert chain) along with my scripts written PHP and CURL to make request.
Here are how certs from my target (http://api.vkontakte.ru) look like in Firefox:
http://speedcap.net/img/bc687485819715c65d6fe1e4ca1fdc40/1a2be.png
Here is a snippet from saved "cert chain X.509 in PEM format" from Firefox (described here: http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/):
-----BEGIN CERTIFICATE-----
MIIFVzCCBD+gAwIBAgIHKx5Ov2FOejANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
[..skip...]
0npsf5fkvT8E13NgVY0PK6V/baMTlTgWXKQZ
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
[..skip...]
qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
U+4=
-----END CERTIFICATE-----
Here is code example of CURL init:
$this->ch = curl_init();
curl_setopt_array($this->ch, array(
CURLOPT_TIMEOUT => 30,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_AUTOREFERER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_SSL_VERIFYPEER => TRUE,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_CAINFO => <path to my cert>,
));
I've got CURL error 60 (CURLE_SSL_CACERT
) complaining about wron cert.
What I've tried:
I've verified that my cert file is used, because when I specify wrong path it complains that it can't find cert (error 70)
I've checked with Facebook SDK and their cert chain that my CURL works with such setup
I've tried to export different chains (including or excluding) last cert in chain
Tried CURLOPT_SSL_VERIFYHOST => 1
.
Any ideas are welcome!
Upvotes: 2
Views: 30987
Reputation: 2190
These are the steps that appear to work:
Then click each level and export every certificate:
Root CA
Server CA and
example-website.invalid.
You should save all three files to your computer. Copy all three files into a single file, e.g. custom_name_cert.pem
Copy that pem file into a directory that is accessible with PHP, ideally the file has permissions 644. You might even go for 444 to prevent tampering, and change it to 644 when you need to update it.
Then update the path in your code, for example:
CURLOPT_CAINFO => '/var/www/certs/custom_name_cert.pem'
WARNING: When the website updates their SSL certificates, the above file may become out of date, and the HTTPS cURL calls may fail, breaking your application. Hopefully someone will answer here with a good way to automate updates to this file.
Upvotes: 3
Reputation: 10362
Vkontakte moved from vkontakte.ru domain to vk.com few years ago. And they change their api handler url too. This is my solution:
This is my code with curl options:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() ."/ffchainvk.crt"); // ok
Where ffchainvk.crt
is file with exported cert chain.
Upvotes: 5
Reputation: 1954
Curl uses CA certificates in a separate location on the server than what the rest of the system, like a desktop would. I have had to install CA certificates into the filesystem before. PHP libcurl will use the libraries that the command line utility uses as well. Please see http://curl.haxx.se/docs/sslcerts.html.
Upvotes: 3