SSL errors using MailChimp's API
I'm trying to connect with MailChimp's API, but keep getting errors:
Error. API call to lists/list failed: SSL peer certificate or SSH remote key was not OK
Then, I created a cacert.pem file and set it in the Mailchimp.php file:
$this->ssl_cainfo = ROOT . DS . 'cacert.pem';
And get this:
Error. API call to lists/list failed: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
or
Error. API call to lists/list failed: SSL peer certificate or SSH remote key was not OK
Per this page:
I tried using the http://curl.haxx.se/docs/caextract.html file for my cacert.pem file, but that gives the "not OK" error listed above.
I also tried making my own with the info provided by our host (a text file, changed extension to .pem, and pasted one and/or both chunks of data into it, making it look like this):
-----BEGIN CERTIFICATE-----
adjkflsdjflkasjdflkajdflksdflsdfkj
asldfkjaadsfhjkfhdsajkfhakjdhfkjdh
....
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
adjkflsdjflkasjdflkajdflksdflsdfkj
asldfkjaadsfhjkfhdsajkfhakjdhfkjdh
....
-----END CERTIFICATE-----
or just one:
-----BEGIN CERTIFICATE-----
adjkflsdjflkasjdflkajdflksdflsdfkj
asldfkjaadsfhjkfhdsajkfhakjdhfkjdh
....
-----END CERTIFICATE-----
At a loss for where to go from here, what to try...etc
Using the example code from here: https://github.com/mailchimp/mcapi2-php-examples
And getting the Vendor files via composer:
"require": {
"mailchimp/mailchimp": ">=2.0.0"
},
Having spoken to MailChimp, the certificate they're still (Jan 2016) using – for compatibility reasons, they told me – is the GTE CyberTrust Global Root (note GTE was bought by Digicert), so you don't need to replace the entire bundle, just add or force PHP to read this certificate:
https://gte-cybertrust-global-root.digicert.com/info/index.html
(note you'll get an 'insecure connection' warning if you try and load that in Firefox, for hopefully obvious reasons – you can add an exception.)
It's in standard .crt format, which is what you need. Guide to certificate formats
You didn't specify what the server was but here's how to add an extra one on Linux without having to replace an entire bundle etc:
On Debian/Ubuntu, certificates live in /etc/ssl/certs/
mailchimp-legacy.crt
sudo c_rehash /etc/ssl/certs
- What's going on here: c_rehash
calculates a short hash of each certificate and creates a symlink from that to the original .pem or .crt file. Basically it's a quick lookup table for openssl - openssl will perform the hash as well and look for the symlink, rather than having to have a database of certificate names or open every file in turn to find the right one. ls -lh *.0 | grep 'mailchimp-legacy.crt'
ls -lh *.0 | grep 'mailchimp-legacy.crt'
You should see something like this:
lrwxrwxrwx 1 root root 20 Feb 13 14:17 4d654d1d.0 -> mailchimp-legacy.crt
lrwxrwxrwx 1 root root 20 Feb 13 14:17 c692a373.0 -> mailchimp-legacy.crt
Alternatively: On Debian, there's also a file called /etc/ca-certificates.conf
and the exclamation mark in the line !mozilla/GTE_CyberTrust_Global_Root.crt
indicates not to use that one. I believe it's possible to put a copy of the certificate with that name under /usr/share/ca-certificates/mozilla
and run sudo update-ca-certificates
, but it seems to me it be likely to be removed again when the package & config file are next updated.
Remember to remove any workarounds you were using - eg - old CA bundles in your certificate directory - anywhere you override CURLOPT_CAINFO in your PHP - an openssl.cainfo line in your php.ini
Check your application works correctly. I didn't need to restart PHP or my webserver, the change was instant. Worth using apt-get update/upgrade
to check you have the most recently certificate packages.
Here's a way to verify SSL connection (and verification) to a specific server from the command line:
echo GET | openssl s_client -CApath /etc/ssl/certs/ -connect us3.api.mailchimp.com:443 2>&1
Monitoring: (updated) MailChimp's v2.0 API (deprecated) has an endpoint called ' helper/ping
' which returns some text to indicate the API status - useful as an automated test of API health and that your certificates are all still working. If you're using v3.0, they recommend using the API Root Resource and appending ?fields=account_name
if you don't actually need to check any of the data.
Someone asked in the comments if this was related to Heartbleed. No. Heartbleed is an openssl vulnerability related to eavesdropping on data in RAM. Mozilla removed GTE CyberTrust (twice) because they wanted to remove all 1024-bit root certificates - research has suggested a nation state could break a 1024-bit prime.
You need the older certificates:
https://github.com/bagder/ca-bundle/blob/e9175fec5d0c4d42de24ed6d84a06d504d5e5a09/ca-bundle.crt
As defined on the page:
http://curl.haxx.se/docs/caextract.html
RSA-1024 removed
Guess Mandrill an Mailchimp use a RSA-1024 version.
That is the one you need. I had the same issue.
Debian and other operating systems and browsers have removed 1024-bit certificates because they are no longer considered secure. But Mailchimp has not switched to a higher-security certificate yet. Therefore you will have to manually re-add the old certificate to you system.
On debian , the correct solution is to follow the instructions in Alternative chain verification failure after 1024b root CAs removal:
First, Go to GTE CyberTrust Global Root and copy the Certificate: section (include -----BEGIN CERTIFICATE-----
and -----END CERTIFICATE-----
. Paste it into the file /usr/share/ca-certificates/mozilla/GTE_CyberTrust_Global_Root.crt
with this command: cat > /usr/share/ca-certificates/mozilla/GTE_CyberTrust_Global_Root.crt
.
Check that it's good with the command: openssl x509 -in /usr/share/ca-certificates/mozilla/GTE_CyberTrust_Global_Root.crt -text -noout
To enable that certificate, add this line to /etc/ca-certificates.conf
: mozilla/GTE_CyberTrust_Global_Root.crt
Update debian's certificates: update-ca-certificates