views:

3586

answers:

3

I'm trying to write a PHP script using cURL that can authorize a user through a page that uses an SSL certificate, in addition to username and password, and I can't seem to get past the SSL cert stage.

In this case, curl_setopt($handle, CURLOPT_VERIFYPEER, 0) unfortunately isn't an option. The certificate is a required part of authentication, otherwise I get the error mentioned in this other similar SO post.

I've tried a few command-line runs with cURL:

> curl --url https://website

This returns the (60) SLL certificate problem error. If I adjust the command to include the --cacert option:

> curl --url https://website --cacert /path/to/servercert.cer

It works just fine; the auth website is returned.

However, I've tried the following PHP code:

$handle = curl_init();
$options = array( 
                  CURLOPT_RETURNTRANSFER => false,
                  CURLOPT_HEADER         => true,
                  CURLOPT_FOLLOWLOCATION => false,
                  CURLOPT_SSL_VERIFYHOST => '0',
                  CURLOPT_SSL_VERIFYPEER => '1',
                  CURLOPT_CAINFO         => '/path/to/servercert.cer',
                  CURLOPT_USERAGENT      => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
                  CURLOPT_VERBOSE        => true,
                  CURLOPT_URL            => 'https://website'
           );

curl_setopt_array($handle, $options);
curl_exec($handle);
if (curl_errno($handle)) {
  echo 'Error: ' . curl_error($handle);
}
curl_close($handle);

I would have thought the code was essentially analogous to the shell commands, but instead I'm greeted with the following error message:

Error: error setting certificate verify locations: CAfile: /path/to/servercert.cer CApath: none

I've read all the literature I can find (particularly on php.net and curl.haxx) and can't seem to find anything that fixes this problem. Any suggestions?

EDIT: I have tried chmod 777 servercert.cer with no success. However, in executing the PHP script with the above code from the command line instead of the browser via php test.php, it works perfectly. Any explanation for why it doesn't work in the browser?

A: 

I would ensure that your libcurl and OpenSSL's are up-to-date.

Also as a simple test, try chmod 0777 on the cacert and see if it works.

WedTM
I'm currently using libcurl/7.16.3 and OpenSSL/0.9.7l. Not the most up-to-date, but certainly not out of date. I forgot to mention in my post that I'd tried chmod 777 on the cacert, with no change.
Magsol
What user are you using to excecute the code as when you go CLI versus with Apache? Try su'ing to the apache user and executing it again.
WedTM
A: 

Maybe the web server doesnt have permissions to perform that operation?

A: 

Oddly enough, this problem vanished entirely when I set both CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER to 0. I left the path to the CA cert intact, and the web application found it without a problem. I'm not sure why all this is the case (worked with the previous configuration from the command line, and works from the browser only with this particular configuration), so if anyone knows and wishes to enumerate, that'd be great. But in terms of a fix, this is it.

Magsol
Setting those variables to false will disable the certificate checks altogether, which is why you stopped seeing the error. This doesn't actually solve the problem.
Justin
I know this isn't ideal, but as I said, it works. I couldn't diagnose the errors I was getting, and this seems to get the job done, so in lieu of any actual fix this is the best answer.
Magsol
Had a very similar issue and this solution worked nicely. Thanks.
canadiancreed
"worked"? It turns off all the safety introduced by SSL. SSL is supposed to make you confident you are talking to a server you expect to be talking. This turns off verification. SEE HERE http://stackoverflow.com/questions/316099/
naugtur