SSL CA Bundles for cURL and PHP

SSL CA Bundles for cURL and PHP

If you've ever tried connecting to a remove service or server using SSL from your server side cURL or PHP script running on a Windows Server, you may very well have encountered the condition that SSL certificate of the remote server cannot be verified.

The problem occurs when you are trying to contact an SSL/TLS secured connection (and have the CURLOPT_SSL_VERIFY_PEER curl option set to true).

The error looks like this:

error:14090086
SSL routines:SSL3_GET_SERVER_CERTIFICATE
certificate verify failed

or may simply return error err 10054

Well, the problem has a very simple solution. CURL cannot talk directly to the Windows certificate repository, so you have to give it a file to validate the Trusted Root Certificate Authority against.

The Solution

There are several options for obtaining a CA certificate bundle:

  • Download one (not entirely recommended but this is the easiest option);
  • Export from a trusted provider (e.g. Mozilla);
  • Export from your Windows CA store;

Download From the Net

To simply download the current pem file, go here:
http://curl.haxx.se/docs/caextract.html
and download the cacert.pem file. (http://curl.haxx.se/ca/cacert.pem)
not that you should trust any source on the internet for guaranteeing the validity of these CA bundles or the security of your server, but I've verified (at least once) that this file is indeed the CA certificate list exported from Mozilla as supplied in the Firefox Browser.

However, if you don't want to trust some random website fro the file, you can...

Get the Mozilla list

The conversion script mk-ca-bundle:

The mk-ca-bundle tool converts Mozilla's cert bundle to PEM format, suitable for (lib)curl and others. Writtten by Guenter Knauf.

Convert from your local Firefox installation (linux):

You can also extract the CA certificate list from your local Firefox installation, if you have the certutil tool installed. You just need to run the firefox-db2pem.sh script (yes, this is a BASH script so you need to be Linux to get this to run).

Export from Windows

Follow these steps to export your Trusted Root Certificate Authority CA certs:

  1. From the windows start menu, run the command "mmc.exe" to launch the Microsoft Management Console;
  2. From the MMC, choose "File" ? "Add/Remove Snap-in..." from the main menu;
  3. Add the Certificates snap-in; When asked which certificates you want to manage, select Computer Account and Local computer;
  4. From the console root, navigate to "Certificates (Local Computer)" > "Trusted Root Certification Authorities" > "Certificates";
  5. Select all of the certificates (CTRL+A) and select "Action" > "All tasks" > "Export..." from the MMC main menu;
  6. Follow the wizard to export the certificate(s) to the Cryptographic Message Syntax Standard - PKCS#7 (.pb7 file) to a file called TrustedRootCAs.pb7;
  7. Open a command prompt (cmd.exe) and navigate to the folder containing the PB7 file you just created;
  8. Run openSSL.exe (you may need to add the path to this program to the Windows PATH environment variable) to convert the file to text using the following command:
    c:\php\extras\openssl\openssl.exe pkcs7 -inform DER -in TrustedRootCAs.pb7 -print_certs -text > TrustedRootCAs.certs

Then, in your PHP application for example, add the following line BEFORE you call curl_exec():

curl_setopt ($ch, CURLOPT_CAINFO, 'C:\PHP\extras\openssl\TrustedRootCAs.certs')

If you're using cURL, just rename the file to curl-ca-bundle.crt and pop it into the same folder as your curl.exe and it should detect it automatically.

That's about all you should need to get things rolling.

Remember, you don't necessarily have to export all of the CA's. In the case of Yubikey, the authentication API server uses a certificate issued by GoDaddy, so you only need export that single on if you prefer not to have to keep this file updated every time ROOT CA certificates are updated by the various providers.