PHP cURL call returning error 56 with NSS error -12195

curlopensslPHPssl

I have an internal server (internal to my network) to which I make a REST API call from my external server.

I don't know if it helps but the external server is running php 5.3.6 with cURL 7.19.7.

To make it safer (other than a Firewall box that limits the external IP addresses that can call my internal server to only the static IP address of my external server), I generated a self-signed SSL Server Certificate for my internal server.

I also generated a Client Certificate to be used by my external server when making the calls.

The calls are being made using the cURL library of PHP. The page that makes the calls looks like this (this page was created as a "proof of concept", to see that the call can actually be made):

<?php 

$mycurl = curl_init();    
$verbose = fopen('curl_error_log','a');    
$url_site = 'https://internal.server.com/api_test.php';

$options = array(
     CURLOPT_HEADER => false                                                
    ,CURLOPT_RETURNTRANSFER => true                                         
    ,CURLOPT_VERBOSE => true                                                
    ,CURLOPT_STDERR => $verbose                                             
    ,CURLOPT_HTTPHEADER => array('Accept: application/json')                
    ,CURLOPT_CAINFO => realpath('/certs/server/certs.pem')  
    ,CURLOPT_CAPATH => realpath('/certs/server')
    ,CURLOPT_SSL_VERIFYPEER => true                                         
    ,CURLOPT_SSL_VERIFYHOST => 2                                            
    ,CURLOPT_SSLCERT => realpath('/certs/client.crt.pem')
    ,CURLOPT_SSLKEY => realpath('/certs/client.key.pem')
    ,CURLOPT_SSLCERTTYPE => 'PEM'
    ,CURLOPT_URL => $url_site
);

curl_setopt_array($mycurl, $options);    
$webResponse =  curl_exec($mycurl);    
fclose($verbose);

?>
<html>
    <head>
        <title></title>
    </head>
    <body>
        <p>Error: <?php echo curl_error($mycurl); ?></p>
        <p>Error no.: <?php echo curl_errno($mycurl); ?></p>
        <p>Result: <?php echo $webResponse; ?></p>
    </body>
</html>

NOTE: a previous iteration of this "proof of concept", without the use of a Client Certificate worked beautifully. In that version, CURLOPT_VERIFYPEER and CURLOPT_VERIFYHOST were set to FALSE and all SSL… and CA… options were absent.

The returning page looks like this:

Error: SSL read: errno -12195

Error no.: 56

Result:

And the verbose file (curl_error_log) has this:

* About to connect() to internal.server.com port 443 (#0)
*   Trying 111.222.333.444... * connected
* Connected to internal.server.com (111.222.333.444) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /certs/server/certs.pem
  CApath: /certs/server
* SSL connection using TLS_DHE_RSA_WITH_AES_128_CBC_SHA
* Server certificate:
*   subject: CN=internal.server.com,OU=BI,O=ABC Corp,L=City,ST=State,C=CO
*   start date: Apr 13 15:15:38 2015 GMT
*   expire date: Apr 12 15:15:38 2016 GMT
*   common name: internal.server.com
*   issuer: CN=internal.server.com,OU=BI,O=ABC Corp,L=City,ST=State,C=CO
> GET /api_test.php HTTP/1.1
Host: internal.server.com
Accept: application/json

* NSS: client certificate from file
*   subject: CN=internal.server.com,OU=BI,O=ABC Corp,L=City,ST=State,C=CO
*   start date: Apr 13 15:26:48 2015 GMT
*   expire date: Apr 12 15:26:48 2016 GMT
*   common name: internal.server.com
*   issuer: CN=internal.server.com,OU=BI,O=ABC Corp,L=City,ST=State,C=CO
* SSL read: errno -12195
* Closing connection #0

Any ideas on what I'm doing wrong or what is missing? Why am I getting this error?

EDIT: I tried playing with CURLOPT_SSLVERSION =>. First I set it to 3 and the error changed slightly. I still got exactly the same verbose output, but towards the bottom, Where it reads "SSL read: errno -12195", it became "SSL read: errno -12271".

Then I change the version to 2, and it crashed earlier giving me "NSS error -12268" around line 6 of the verbose output.

Finally, when I tried 4 or 5, the verbose file was exactly the same as above.

Thanks.

Best Answer

After posting the same question in the cURL website, I got a few answers that gave me new ideas that I tried and solved the problem, so I decided to post them here, in case someone else has similar problems:

The first clue was the error codes themselves (-12195, -12271, -12268). Someone gave me a URL that explains all of them:

http://www-archive.mozilla.org/projects/security/pki/nss/ref/ssl/sslerr.html

I also went back and regenerated all my Certificates, following a different recipe and using more specific parameters. I can't say for sure that it made a difference (the errors kept happening), but without doing this, I'm pretty sure the next step (the final one that made the error disappear), would not work...

The final step (stupid as it is) was to use a different file format for the CA Certificate file. Instead of PEM, I use CRT. Once I changed it (without any other change), the error disappeared and my calls started to work.

I hope it will help someone out there...

Related Topic