After upgrading to PHP 5.6 I get an error when trying to connect to a server via fsockopen()
..
The certificate on the server (host) is self-signed
PHP Warning: fsockopen(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
if($fp = fsockopen($host, $port, $errno, $errstr, 20)){
$this->request = 'POST '.substr($this->url, strlen($this->host)).' HTTP/1.1'.$crlf
.'Host: '.$this->host.$crlf
.'Content-Length: '.$content_length.$crlf
.'Connection: Close'.$crlf.$crlf
.$body;
fwrite($fp, $this->request);
while($line = fgets($fp)){
if($line !== false){
$this->response .= $line;
}
}
fclose($fp);
}
# cd /etc/ssl/certs/
# wget http://curl.haxx.se/ca/cacert.pem
php.ini
openssl.cafile = "/etc/ssl/certs/cacert.pem"
But the script still fails to work
This works
echo file_get_contents("/etc/ssl/certs/cacert.pem");
$contextOptions = array(
'ssl' => array(
'verify_peer' => true, // You could skip all of the trouble by changing this to false, but it's WAY uncool for security reasons.
'cafile' => '/etc/ssl/certs/cacert.pem',
//'CN_match' => 'example.com', // Change this to your certificates Common Name (or just comment this line out if not needed)
'ciphers' => 'HIGH:!SSLv2:!SSLv3',
'disable_compression' => true,
)
);
$context = stream_context_create($contextOptions);
$fp = stream_socket_client("{$host}:{$port}", $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $context);
error
PHP Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Add
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
));
before
mail->send()
and replace
require "mailer/class.phpmailer.php";
with
require "mailer/PHPMailerAutoload.php";
Have you tried using the stream_context_set_option()
method ?
$context = stream_context_create();
$result = stream_context_set_option($context, 'ssl', 'local_cert', '/etc/ssl/certs/cacert.pem');
$fp = fsockopen($host, $port, $errno, $errstr, 20, $context);
In addition, try file_get_contents()
for the pem file, to make sure you have permissions to access it, and make sure the host name matches the certificate.
In my case, I was on CentOS 7 and my php installation was pointing to a certificate that was being generated through update-ca-trust
. The symlink was /etc/pki/tls/cert.pem
pointing to /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
. This was just a test server and I wanted my self signed cert to work properly. So in my case...
# My root ca-trust folder was here. I coped the .crt file to this location
# and renamed it to a .pem
/etc/pki/ca-trust/source/anchors/self-signed-cert.pem
# Then run this command and it will regenerate the certs for you and
# include your self signed cert file.
update-ca-trust
Then some of my api calls started working as my cert was now trusted. Also if your ca-trust gets updated through yum or something, this will rebuild your root certificates and still include your self signed cert. Run man update-ca-trust
for more info on what to do and how to do it. :)
I faced a similar issue during work with Ubuntu 16.04 by using Docker. In my case that was a problem with Composer, but error message (and thus the problem) was the same.
Because of minimalist Docker-oriented base image I had missing ca-certificates
package and simple apt-get install ca-certificates
helped me.
Firstable, make sure that you Antivirus software doesn't block SSL2.
Because I could not solve a problem for a long time and only disabling the antivirus helped me
You mention the certificate is self-signed (by you)? Then you have two choices:
cacert.pem
from cURL website won't do anything, since it's self-signed)Here's a list of SSL context options in PHP: https://secure.php.net/manual/en/context.ssl.php
Set allow_self_signed
if you import your certificate into your trust store, or set verify_peer
to false to skip verification.
The reason why we trust a specific certificate is because we trust its issuer. Since your certificate is self-signed, no client will trust the certificate as the signer (you) is not trusted. If you created your own CA when signing the certificate, you can add the CA to your trust store. If your certificate doesn't contain any CA, then you can't expect anyone to connect to your server.
If you are using macOS sierra there is a update in PHP version. you need to have Entrust.net Certificate Authority (2048) file added to the PHP code. more info check accepted answer here Push Notification in PHP using PEM file
The problem is in new PHP Version in macOS Sierra
Please add
stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
Source: Stackoverflow.com