PHP SoapClient: failed certificate verification - php

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?

Related

Laravel beyondcode websockets - doesn't work if verify_peer is true

I'm using the package beyondcode/laravel-websockets.
My problem here is when I set the 'verify_peer' => true the websocket is not working, but when the value is false it is working. Is there anyone here managed to make this to work?
For production website, I want set the verify_peer to true to prevent man-in-the-middle attack.
I have a website, lets say aceraven777.com, it already has SSL installed (in the cPanel it has autoSSL enabled).
In the websockets config I entered the same path (the one that cPanel generated) for the certificate and private key.
The chrome throws an error:
WebSocket connection to 'wss://aceraven777.com:6001/app/asdfswerqwsafasfd?protocol=7&client=js&version=4.3.1&flash=false' failed:
createWebSocket # pusher.min.js:8
This is the error in firefox:
Firefox can’t establish a connection to the server at wss://aceraven777.com:6001/app/asdfswerqwsafasfd?protocol=7&client=js&version=4.3.1&flash=false. pusher.min.js:8:6335
Below are the settings I used:
config/websockets.php
'ssl' => [
/*
* Path to local certificate file on filesystem. It must be a PEM encoded file which
* contains your certificate and private key. It can optionally contain the
* certificate chain of issuers. The private key also may be contained
* in a separate file specified by local_pk.
*/
'local_cert' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT', null),
/*
* Path to local private key file on filesystem in case of separate files for
* certificate (local_cert) and private key.
*/
'local_pk' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_PK', null),
/*
* Passphrase for your local_cert file.
*/
'passphrase' => env('LARAVEL_WEBSOCKETS_SSL_PASSPHRASE', null),
'verify_peer' => true,
],
config/broadcasting.php
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'host' => env('PUSHER_APP_HOST'),
'port' => env('PUSHER_APP_PORT'),
'useTLS' => true,
'scheme' => 'https',
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 1,
CURLOPT_SSL_VERIFYPEER => 1,
],
],
// Configuration for laravel mix JS
'mix' => [
'host' => env('MIX_PUSHER_APP_HOST'),
'key' => env('MIX_PUSHER_APP_KEY'),
'cluster' => env('MIX_PUSHER_APP_CLUSTER'),
'port' => env('MIX_PUSHER_APP_PORT'),
],
],
You probably need to specify a Certificate Authority file on the local filesystem.
This is the source of 95% of these errors on production servers.
The other 4% are caused by self-signed certificates, which I doubt you have in a production environment.
You will need to modify your config/websockets.php
'ssl' => [
// ...
'capath' => env('LARAVEL_WEBSOCKETS_SSL_CA', null),
],
The CA path typically a directory similar to /etc/ssl/certs/.
If this does not work try allowing self-signed certs:
'ssl' => [
// ...
'allow_self_signed' => true,
],
For more information, you should look at the PHP specification for SSL verify peer.
This article helped me a lot some time ago implementing websockets especially with SSL certificate:
https://christoph-rumpel.com/2020/11/laravel-real-time-notifications
You also have git repositories telling you how to implement with and without SSL.
To me it seems, you are not connecting to the correct port.
PusherJs uses default web ports 80 and 443, as described here: https://pusher.com/docs/channels/library_auth_reference/pusher-websockets-protocol
Change the port inside your .env file

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,
...
]

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

PHP 7 and SOAP WSDL with SSL error

I'm using Wsdl2PhpGenerator to create my soap client; was was working fine with PHP v5.4, but now I've upgraded to PHP 7 I get an error:
Uncaught SoapFault: SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://sussexbedcentre.retailsystem.net/services/v2/GetCatalog.asmx?WSDL' : failed to load external entity
I have tried:
Connecting to a non SSL soap service - worked fine, so must be the SSL.
Every ssl_method
soap.wsdl_cache_enabled, soap.wsdl_cache_ttl, soap.wsdl_cache all set to 0
Verified openssl, soap, xmlrpc php extensions all loaded ok
PEM file and passphrase worked fine under PHP 5.4
Any ideas what else I can try to get to the bottom of this?
Code I'm using is:
$cert = 'rs_ssl.pem';
$generator = new \Wsdl2PhpGenerator\Generator();
$generator->generate(
new \Wsdl2PhpGenerator\Config(array(
'inputFile' => 'https://sussexbedcentre.retailsystem.net/services/v2/GetCatalog.asmx?WSDL',
'outputDir' => 'soapclass/',
'soapClientOptions' => array(
'local_cert' => $cert,
'passphrase' => '*******',
'connection_timeout' => 60,
'trace' => 1,
'soap_version' => SOAP_1_2
)
))
);
If I switch back to PHP 5.4 with the same code it works fine.
Thanks!

PHP verify failed with LetsEncrypt

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']
]
));

Categories