Verify Peer setting with RightNow cURL

When making an HTTPS connection with cURL, it is essential to validate the certificate of the host you are connecting to. While it is possible to turn off this verification using the CURLOPT_SSL_VERIFYPEER cURL configuration, it leaves your code vulnerable to man in the middle attacks.

Other developers I know (myself included) tend to turn off PEER verification while doing initial development because dealing with certs is often a PITA. I always tell myself, I'll just deal with that later; I have much more important business logic to write.

If you are using an external service whose certificate is signed by a trusted Root Certificate Authority (i.e. Verisign etc), you can use this little trick to immediately enable SSL Peer verification in cURL without having to go through the hassle of uploading a certificate yourself and explicitly referencing it. All RightNow sites contain a certificate bundle of trusted Root CA's. This bundle is maintained by Oracle and can be utilized in your custom cURL setup.

The bundle is located at the following path where DBNAME is the name of your site's database:

  • /cgi-bin/DBNAME.db/certs/ca.pem

You can dynamically construct this path using the CP framework so that it is portable between your production and clone sites.

CP2 Example


<?php
$ca_path = sprintf('/cgi-bin/%s.db/certs/ca.pem', getConfig(DB_NAME));

CP3 Example


<?php
$ca_path = sprintf('/cgi-bin/%s.db/certs/ca.pem', \RightNow\Utils\Config::getConfig(DB_NAME));

One you have the CA file path, you simply set it using the CURLOPT_CAINFO option.

Example w/ Verify Peer


<?php
    //Note: GoogleAPI's are available even on Secure Pods.
    $url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=RightNow%20CX";
 
    //Do cURL stuff
    $ch = \curl_init();
    \curl_setopt($ch, CURLOPT_URL, $url);
    \curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
    \curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    \curl_setopt($ch, CURLOPT_CAINFO, $ca_path); //from above
    \curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $body = \curl_exec($ch);
    \curl_close($ch);

    print "<pre>";
    print_r($body);
    print "</pre>";

This only works if your service's certificate is signed by a trusted Root CA. In general, the Oracle provided bundle is similar to the Mozilla reference bundle. The other benefit is that this bundle is maintained by Oracle, so as Root CA certificate's expire it will be automatically updated. You don't have to (theoretically) perform any certificate maintenance of your own.

If your service uses a self-signed certificate, this method won't work and you'll need to continue manually uploading and referencing your certificate files.

Comments

Thanks for the post. I could clearly understand the VERIFYPEER setting now in cURL functionality. Good job!! Keep rocking!!!

Im getting stuck on getting the db_name
Im testing this out in custom files so i can output results but the code simply stops on getting the db_name whichever method i use as youve shown - even if i try catch, it just stops

eg
$ca_cert = sprintf('/cgi-bin/%s.db/certs/ca.pem', \RightNow\Utils\Config::getConfig(DB_NAME));
echo $ca_cert."";

\RightNow\Utils\Config::getConfig is a CP specific method. It won't work in scripts/custom files.

There are likely other direct methods available that can be called from scripts/custom to get config values (and establish the necessary constants), but I don't recall what those are. Some reflection via PHP might give you what you need, or perhaps looking at the CP core files to see what is going on under the hood.

Zircon - This is a contributing Drupal Theme
Design by WeebPal.