in PHP, Programming, Web

The Secret to cURL in PHP on Windows…

cURL is a great library created by Daniel Stenberg, that allows you to connect and communicate to many different types of servers using many different types of protocols. In particular, it’s used heavily in PHP to communicate to Payment Gateways and fetch XML feeds from other sites whilst being ‘transparent’ to web page visitors.

The particular secret I would like to share involves establishing connections to secure sites (SSL-enabled ones in particular). When you browse to an SSL–enabled site in your web browser, a few things happen… One of the things that happen is that your browser checks to see if the site’s security certificate is trusted. It does this by checking the entity that signed the certificate against it’s built in book of trusted signatures and if it finds a match, onto the next step. However, if your browser can’t find a match the certificate will be invalid and it will complain that the site could potentially be a fake or insecure.

The ‘book of trusted signatures’ is known as a Certificate Authority bundle and usually comes built in with most web browsers. If you install cURL (the standalone version that can be run from the command–line), chances are it will come with the cURL Certificate Authority bundle and you won’t need to do a thing as the cURL functions within PHP will use this as it’s book of trusted signatures. However, on Windows the cURL functions within PHP are pre–built and included in the standard PHP setup, thus do not include this bundle. Chances are if you don’t know this you’ll probably spend a good amount of your time screaming at your webpage as it mocks you with error number 60! I know I spent quite a good few hours wondering why it worked on my Linux PC but not on the Windows server!

CURL Error 60: SSL certificate problem, verify that the CA cert is OK.
Details: error:14090086:SSL routines
SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Luckily the fix is quite easy…

  1. Download standalone cURL for Windows (make sure it is the SSL version).
    Download the .pem file from the cURL site and rename the extension to .crt
  2. Extract curl-ca-bundle.crt from the download and copy to your web server folder.
  3. Add the following line to your code: –
    curl_setopt($ch, CURLOPT_CAINFO, "c:/path/to/ca-bundle.crt");
  4. Remember to change $ch to the variable you’ve assigned your curl connection to and “c:/path/to/ca-bundle.crt” to the location of where you have copied the ca-bundle.crt.
  5. Check the server has permission to read this file.

If you are getting started with cURL, here is some sample code I’ve written that should get you started. It outputs the contents of the secure server to a string, which is echoed out to your page.

// Set up cURL connection
$url = 'https://www.verisign.com/';
$ca = 'c:/path/to/ca-bundle.crt';
$ch = curl_init();

// Apply various settings
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0); // Don’t return the header, just the html
curl_setopt($ch, CURLOPT_CAINFO, $ca); // Set the location of the CA-bundle
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Return contents as a string

$result = curl_exec ($ch);
curl_close($ch);
echo $result;

That’s it! You should now be able to connect successfully to SSL-enabled websites using the cURL functions of PHP on your Windows server.

UPDATE 2010/08/20: Apparently the certificates aren’t shipped with the archived versions any more. To get the latest certificate bundle that’s been extracted from the Mozilla browser you can download the .pem file from the cURL site and rename the extension to .crt.

Write a Comment

Comment

45 Comments

  1. Hello, thanks for the post! I was just struggling with the same problem myself. But, I’m also having this problem in my Linux machine, with a different explanation:

    SSL certificate problem, verify that the CA cert is OK. Details:
    error:14090086:SSL routines:func(144):reason(134)

    Do you know how to fix it in Linux?

    It’s seems to work for CURL but what about other PHP functions like fope, file_get_contents and the stream functions?

    Thanks

  2. Thanks so much! I don’t know why they don’t just include this critical piece with the PHP install.

    You saved me a lot of time!

    Jim

  3. Thanks for the great post; and highly useful update! The error “60” had me going, particularly since we do most of our development on Linux boxes.

    Thank you thank you!

  4. i have downloaded the file cacert.pem file and rename it now how can i Extract curl-ca-bundle.crt…

    My OS is Windows7.
    Please Advice me….

  5. I am getting this error for my wordpress while installing the plugin .

    Please can you enlighten on how to follow these below steps : 2 -4 , i am all confused, where to extract the file and where to add the code …its all very confusing.

  6. Great post mate.

    This fixed my problem trying to run the PHP SDK for Amazon Web Services from my local development machine.

      • Np Ben. Did you find this link via Google? I wrote this blog post almost 5 years ago now. Amazed anyone still finds this link!

  7. Hello Richard,

    Im working with nusoap, and ssl, with a selfsigned certificate, i set those variables:

    $oSoap->scheme=”https”;
    $oSoap->authtype = ‘certificate’;
    $oSoap->certRequest[‘cainfofile’]=”/etc/pki/tls/certs/ca-bundle.crt”;
    $oSoap->certRequest[‘verifypeer’]=true;
    $oSoap->certRequest[‘verifyhost’]=2;

    in ca-budnle file i concatenate the certificate from the site i want to has access.

    and im reciving:

    Error [HTTP Error: cURL ERROR: 60: SSL certificate problem, verify that the CA cert is OK. Details:
    error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

    The thing is i must go trough https, because is a secured server and only works in that way.

    Can You give me an advice?

  8. Hi, i have this error.
    but i didnt solve my problem. Please help me.
    “SSL certificate problem, verify that the CA cert is OK. Retrying with the CA cert bundle from google-api-php-client.

    error

  9. Although this describes a fix in a Windows environment, might a procedure similar to this resolve this problem in a Linux-based environment using CentOS?

  10. Just another tip: the path to the crt or pem file needs to be absolute, relative paths don’t work. You can use realpath(); to overcome this

  11. Thanks for you help I was trying to figure out why cURL was working on my test server but not my dev laptop. Spent a good 1/2 a day on this before reading your site

  12. Thanks for saving me such a major headache.

    If only the error message said your need the “certificate file stored locally on your pc and which php param to set”

Webmentions

  • Google Calendar API v3 cant supplement eventuality php | Zheng February 3, 2020

    […] is some information during this link that describes how to repair a […]

  • SoundCloud Sound Competition | Best WordPress Plugins & Themes February 3, 2020

    […] If your website is on a windows server and you get the following error: “The requested URL responded with HTTP code 0″ you might have a problem with cURL with your setup, please see the following link to resolve: http://richardwarrender.com/2007/05/the-secret-to-curl-in-php-on-windows/ […]

  • Facebook login (facebook2t3) - TYPO3 Forum & Portal February 3, 2020

    […] […]