PHP verify failed with LetsEncrypt - php

Having an issue when trying to read a stream :
$result = file_get_contents($url, false, stream_context_create(
['http' => ['timeout' => (float) $this->options['timeout']]]
));
SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
Before anyone answers i am not going to do
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
Am hoping someone else has used letsencrypt and has some proper way of making sure its validated.
feel free to check my cert on my domain lukepolo.com

openssl.cafile=
curl.cainfo=
in your php.ini , you need both

You'll probably have to install the CA certificate (this page has links to download the CA file). You might have to try each of the various signed to get it to work. Get the PEM version and save it to your server and then change your code like so
$result = file_get_contents($url, false, stream_context_create(
[
'http' => ['timeout' => (float) $this->options['timeout']],
'ssl' => ['cafile' => '/path/to/file.pem']
]
));

Related

I am using laravel version 6. I received below error when try to reset password. How can I Solve this error [duplicate]

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
code
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);
}
Have tried
# 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
update
This works
echo file_get_contents("/etc/ssl/certs/cacert.pem");
update 2
$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
The file that you downloaded (http://curl.haxx.se/ca/cacert.pem) is a bundle of the root certificates from the major trusted certificate authorities. You said that the remote host has a self-signed SSL certificate, so it didn't use a trusted certificate. The openssl.cafile setting needs to point to the CA certificate that was used to sign the SSL certificate on the remote host. PHP 5.6 has been improved over previous versions of PHP to now verify peer certificates and host names by default (http://php.net/manual/en/migration56.openssl.php)
You'll need to locate the CA certificate that was generated on the server that signed the SSL certificate and copy it to this server. If you're using self-signed certificates, you'll need to add the CA cert that was used to sign the remote host's SSL certificate to the trusted store on the server you're connecting from OR use stream contexts to use that certificate for each individual request. Adding it to the trusted certificates is the simplest solution. Just add the contents of the remote host's CA cert to the end of the cacert.pem file you downloaded.
Previous:
fsockopen doesn't support stream contexts, so use stream_socket_client instead. It returns a resource that can be used with all the commands that fsockopen resources can.
This should be a drop in replacement for the snippet you have in your question:
<?php
$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("tcp://{$host}:{$port}", $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $context);
if (!$fp) {
echo "$errstr ({$errno})<br />\n";
}else{
$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 (!feof($fp)) {
$this->response .= fgets($fp);
}
fclose($fp);
}
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.
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";
The problem is in new PHP Version in macOS Sierra
Please add
stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
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. :)
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
I used the following script to check the issue
<?php
$url = "mail.example.com";// your host which has issue
$orignal_parse = parse_url($url, PHP_URL_HOST);
$get = stream_context_create(array("ssl" => array("capture_peer_cert" => TRUE)));
$read = stream_socket_client("ssl://".$url.":993", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $get);
if (!$read) {
// ssl connection failed for some reason
// could be a certificate error or failure to connect on port 443
echo "Failed to connect to site. Error {$errno}: {$errstr}\n";
} else {
$cert = stream_context_get_params($read);
$certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']);
var_dump($certinfo);
}
?>
I was getting below 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
Updated ca certificates and then ran reinstall that helped
yum reinstall ca-certificates
You mention the certificate is self-signed (by you)? Then you have two choices:
add the certificate to your trust store (fetching cacert.pem from cURL website won't do anything, since it's self-signed)
don't bother verifying the certificate: you trust yourself, don't you?
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
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.

PHP Laravel cURL SSL certificate problem: unable to get local issuer certificate

I my project written in Laravel I have method that get number value from server:
public static function getAddressApiBalance()
{
try {
$uri = "https://btczexplorer.blockhub.info/ext/getbalance/t1ZYiG4R4n5gTgUKZRgVpKPzG5FYQXpEqga";
$response = Http::get($uri);
return $response;
...
And when I call this code I get error in my browser:
cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
You can disable ssl verification (not recommended!, but quick and easy for dev) :
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
or with guzzle :
$client = new Client(['verify' => false]);
or you can download a cacert.pem file :
https://curl.haxx.se/ca/cacert.pem
and edit your php ini with the path of cacert :
openssl.cafile=/etc/ssl/cacert.pem
\Illuminate\Support\Facades\Http::withOptions([]) accept guzzlet http options
https://docs.guzzlephp.org/en/stable/request-options.html#verify
In Laravel 8 you can use Http API which is easier but still use Guzzle HTTP client behind the scenes. In that case you can disable certificate validation like this:
$client = Http::withOptions([
'debug' => true,
'verify' => false,
])
->get('https://btczexplorer.blockhub.info/ext/getbalance/t1ZYiG4R4n5gTgUKZRgVpKPzG5FYQXpEqga', [
'parameter1' => '1234567',
'parameter2' =>'890',
]);
Of course debug option is not required to disable ssl checking but it helps with testing. Also parameters are just to show how to add them to the request.
You have 3 options to solve that problem (3 way I know) :
1 -> Download certificate file (https://curl.haxx.se/ca/cacert.pem) and move it to your php file. Edit your php.ini after it for the cerfificate file.
2 -> Use verify option in your Request to disable ssl verification
Http::withOptions([
'verify' => false,
])...
3 -> Find Guzzle Client folder to disable ssl for all request
File Locate : \vendor\guzzlehttp\guzzle\src\Client.php
Function : configureDefaults
$defaults = [
'allow_redirects' => RedirectMiddleware::$defaultSettings,
'http_errors' => true,
'decode_content' => true,
'verify' => app()->env == "local" ? false : true,
'cookies' => false,
'idn_conversion' => true,
];
Normally verify => true as default. If you edit it only for your local, use it as me or you want to disable it for everything you can use as below.
$defaults = [
...
'verify' => false,
...
]

PHP SoapClient: failed certificate verification

I'm trying to send a soap request to some url. My SOAP options are:
array(
'location' => 'https://some_url/',
'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
'trace' => 1,
'soap_version' => SOAP_1_2,
'connection_timeout' => 60,
'stream_context' => stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'allow_self_signed' => true,
'cafile' => 'cacert.crt', // This file really exists, checked that
]
])
);
I get the following error:
SoapClient::__doRequest(): SSL operation failed with code 1. OpenSSL Error messages:
error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01
error:04067072:rsa routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed
error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
So I googled for "block type is not 01", but the results are pretty scarce. One might think that ca cert is wrong, but I fetched it with Chromium's Developer tools (Security tab) when I was on a page representing my url. Just to make sure that it's ok I put it in my browser and that page opens without any security warnings, showing me an XML response.
Putting it in /usr/share/ca-certificates/ had no effect either.
Certificate has pem encoding.
verify_peer set to false is not an option of course.
My php version is 5.5.17-2, the same behaviour is observed on PHP 7.0.21-1 though. OS is Ubuntu 16.04. OpenSSL 1.0.1 14 Mar 2012, the same effect on OpenSSL 1.0.2g-fips 1 Mar 2016.
Any thoughts?

unable to Curl or SoapClient Any remote_server:8080 port on Directadmin Centos

I am Trying To Connect a Soap Api by php
ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache_ttl',0);
$opts = array(
'ssl' => array('ciphers'=>'RC4-SHA', 'verify_peer'=>false, 'verify_peer_name'=>false)
);
$params = array ('encoding' => 'UTF-8', 'verifypeer' => false, 'verifyhost' => false, 'soap_version' => SOAP_1_1, 'trace' => 1, 'exceptions' => 1, "connection_timeout" => 5, 'stream_context' => stream_context_create($opts) );
$url = "http://x.x.x.x:8080/ws-relay/MessageRelayService?wsdl";
$client =new SoapClient($url,$params);
$result = $client->sendMessageOneToMany(array(
"username" => 'xxxxx',
"password" => 'xxxxx',
"originator" => "50004132311446",
"destination" => $numbers,
"content" => $massage,
));
but it allways got an
SOAP-ERROR: Parsing WSDL: Couldn't load from 'x.x.x.x:8080/ws-relay/MessageRelayService?wsdl";' : failed to load external entity "x.x.x.x:8080/ws-relay/MessageRelayService?wsdl";")
error !
I also Tried to Curl This WSDL but I got
[root#myhost ~]# curl http://x.x.x.x:8080/ws-relay/MessageRelayService?wsdl
curl: (7) Failed to connect to x.x.x.x port 8080: Connection timed out
Error !
so i also tried to curl portquiz.net:8080/ for test and i got timeout again !
is there some rule in firewall that block me to send request to 8080 ports !
how can i unblock it in centos directadmin vps ?
often this happens because that your ip address has been blocked , or there are an issues with the server it self .
for more info about that , libcurl error codes
CURLE_COULDNT_CONNECT (7)
Failed to connect() to host or proxy.
for your command :
curl http://xx.xx.xx.xx:xxxxws-relay/MessageRelayService?wsdl
when executing it in my own pc i got the response normally .
so you will need to use proxy in your SoapClient class
For making an HTTP connection through a proxy server, the options
proxy_host, proxy_port, proxy_login and proxy_password are also
available.
so you will need to add some params to your $params array ass follows :
$params['proxy_host'] = "proxy_ip";
$params['proxy_port'] = "proxy_port";
it's also possible (personally i recommend this) to use procedures libcurl functions or packages built on it.
if you want to use the cli way , so your command may be some thing like this :
curl http://xx.xx.xx.xx:xxxx/ws-relay/MessageRelayService?wsdl -x "ip_address:ip_port"
for socks5 ips
curl http://xx.xx.xx.xx:xxxx/ws-relay/MessageRelayService?wsdl -x "ip_address:ip_port" --socks5

Uncaught CurlException: 77 : error setting certificate verify locations

I keep getting this same error. I just installed the SSL and no luck. I have checked out all the other posts but none of the solutions seemed to work for me.
Does anyone know what should I be doing ?
Fatal error: Uncaught CurlException: 77: error setting certificate
verify locations: CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath:
none thrown in
/home/acmesoft/public_html/Oddsmaker/php_sdk/base_facebook.php on line
977
if ($result === false) {
$e = new FacebookApiException(array(
'error_code' => curl_errno($ch),
'error' => array(
'message' => curl_error($ch),
'type' => 'CurlException',
),
));
curl_close($ch);
throw $e;
}
curl_close($ch);
return $result;
Riyanto Wibowo's response is dangerous because you're essentially turning off SSL. Be wary of taking that route. From a comment on the php manual:
Please everyone, stop setting CURLOPT_SSL_VERIFYPEER to false or 0. If your PHP installation doesn't have an up-to-date CA root certificate bundle, download the one at the curl website and save it on your server:
http://curl.haxx.se/docs/caextract.html
Then set a path to it in your php.ini file, e.g. on Windows:
curl.cainfo=c:\php\cacert.pem
Turning off CURLOPT_SSL_VERIFYPEER allows man in the middle (MITM) attacks, which you don't want!
I would have posted this as a comment but I don't have enough reputation.
I have the same error with you and this problem was solved, I just put this 2 lines
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYPEER] = false;
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYHOST] = 2;
after your facebook apps definition
$facebook = new Facebook(array(
'appId' => 'xxx',
'secret' => 'xxx',
'cookie' => true,
'perms' => 'publish_stream,read_stream,email',
'domain' => 'example.com'
))
You just need to have fb_ca_chain_bundle.crt in the same folder as base_facebook.php. You can get it here: https://github.com/facebook/facebook-php-sdk/blob/master/src/fb_ca_chain_bundle.crt

Categories