# Fatal Error with Google API

Hi Experts,

This is a  weird issue. I have been developing a small PHP App on my Dev Server (IIS7) with Google Calendar API, then launched it on my live Server (IIS8). At that time, the connection to the API worked from both servers, which was a month back.

While the connection from my Live Server continues to work, on my Dev Server I get
PHP Fatal error:  Uncaught GuzzleHttp\Ring\Exception\RingException: Error creating resource: [message] fopen(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
[line] 406
[message] fopen(): Failed to enable crypto
[line] 406
[message] fopen(https://www.googleapis.com/oauth2/v4/token): failed to open stream: operation failed
[line] 406


You can see a working version on my Live Server here:

A success result is a JSON object.

The error suggest a  SSL issue, but as you can see by the URL, https is not used.

Actually for my Live Server I  have support, and they were supposed to replace cacert.pem under Plesk. On my Dev, i don't have Plesk, and did not need to replace cacert.pem, or don't know how

Thank you
###### Who is Participating?

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Software DeveloperAuthor Commented:
Developer & EE ModeratorCommented:
I develop on PHP for windows myself. When something like this happens, I have to specify where my local PEM file is.

https://curl.haxx.se/docs/sslcerts.html
https://curl.haxx.se/docs/caextract.html

I just pull the cert.pem from that second link and place it in my webroot. Then somewhere in your code for your cURL or other api call you will need to specify where it is. Something like below.

 'cert' => '/path/to/cert.pem'


In my case, I also add the intermediate cert for my provider.
Software DeveloperAuthor Commented:
I have been to those links before, but the problem is I dont know to do with the cacert.pem when I download it. How do I add it to my web server and/or browser?
Developer & EE ModeratorCommented:
Put it somewhere on your server that you have given access to the internet user.  If you put it outside of the www folder, make sure the intenet user has access. You can put it inside the www and then access it that way.

For Authorize.net as example you can see on line 18 of this code. This is the httpclient.php file.  You probably have something similar. I think I always had problems and downloaded the pem file from hax, then added the intermediate cert from my provider to the pem file.
 public function _sendRequest($xmlRequest) {$xmlResponse = "";

$post_url =$this->_getPostUrl();
$curl_request = curl_init($post_url);
curl_setopt($curl_request, CURLOPT_POSTFIELDS,$xmlRequest);
curl_setopt($curl_request, CURLOPT_HEADER, 0); curl_setopt($curl_request, CURLOPT_TIMEOUT, 45);
curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl_request, CURLOPT_SSL_VERIFYHOST, 2);

$this->logger->info(sprintf(" Url: %s",$post_url));
// Do not log requests that could contain CC info.
$this->logger->info(sprintf("Request to AnetApi: \n%s",$xmlRequest));

if ($this->VERIFY_PEER) { curl_setopt($curl_request, CURLOPT_CAINFO, dirname(dirname(__FILE__)) . '/../../ssl/cert.pem');
} else {
$this->logger->error("Invalid SSL option for the request"); return false; } if (preg_match('/xml/',$post_url)) {
curl_setopt($curl_request, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml")); // file_put_contents($this->_log_file, "\nSending 'XML' Request type", FILE_APPEND);
$this->logger->info("Sending 'XML' Request type"); } try {$this->logger->info("Sending http request via Curl");
$xmlResponse = curl_exec($curl_request);
$this->logger->info("Response from AnetApi:$xmlResponse");

} catch (\Exception $ex) {$errorMessage = sprintf("\n%s:Error making http request via curl: Code:'%s', Message:'%s', Trace:'%s', File:'%s':'%s'",
$this->now(),$ex->getCode(), $ex->getMessage(),$ex->getTraceAsString(), $ex->getFile(),$ex->getLine() );
$this->logger->error($errorMessage);
}
if ($this->logger &&$this->logger->getLogFile()) {
if ($curl_error = curl_error($curl_request)) {
$this->logger->error("CURL ERROR:$curl_error");
}

}
curl_close($curl_request); return$xmlResponse;
}

Software DeveloperAuthor Commented:
Developer & EE ModeratorCommented:
Does your php.ini have something that looks like:

curl.cainfo=c:\path\to\cacert.pem


Perhaps you can update your ini file or in your app's config file. I suspect once you update that it will work. Since it is on your dev server, you can probably updated it directly on the php.ini file though.

Experts Exchange Solution brought to you by