I have installed WAMP 3.0.4 and am trying to write a PHP script that connects to an external HTTPS web service. But this returns the error:
Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
I have written a short script that demonstrates the issue:
<?php
$auth = base64_encode('username:password');
$aContext = array(
'http' => array(
'proxy' => 'tcp://proxyip:proxyport',
'request_fulluri' => true,
'header' => 'Proxy-Authorization: Basic $auth'
),
'SSL' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
'cafile' => 'C:/wamp/certificates/cacert.pem'
)
);
$cxContext = stream_context_create($aContext);
$sFile = file_get_contents("https://www.google.com", False, $cxContext);
echo $sFile;
?>
It is a requirement to use a proxy server.
As can be seen, I have tried installing a root certificates bundle and also adding verify_peer to false (not that I would do that in production) but still I receive this error.
As can be clearly seen from the above, I am something of an Apache / WAMP novice. Can someone perhaps explain what I am missing?
If you want to disable the verification of the SSL connection you can use:
'verify_peer' => false
And inside your code:
<?php
$auth = base64_encode('username:password');
$aContext = array(
'http' => array(
'proxy' => 'tcp://proxyip:proxyport',
'request_fulluri' => true,
'header' => "Proxy-Authorization: Basic $auth"
),
'ssl' => array(
'verify_peer' => false,
),
);
$cxContext = stream_context_create($aContext);
$sFile = file_get_contents("https://www.google.com", False, $cxContext);
echo $sFile;
?>
However note that this means that no-one is guarantee you that the data you get is authentic (since the ssl certificate is NOT verified).
If you want to verify the certificate, you should use the root certificates as in your question, however, you said you work with WAMP so the path to your cafile should be something like:
"cafile" => "c:/wamp/certificates/cacert.pem",
More important - you said nothing regarding the proxy in your question. Is it something that you need or is it something you found somewhere and just trying to use?
If you don't need the proxy just remove if from your request.
While on MAMP on macOS, simply restarting MAMP server solved this issue for me.
Related
I hope this question won't be marked as duplicate as I read many related questions and answers on the site: although I tried most of the suggestions out there I still couldn't resolve my problem.
My codebase : (I left comments on purpose to give an idea of what I have been trying so far, based on my browsing)
try {
$opts = array(
//~mrossw 'http' => array(
//~mrossw 'user_agent' => 'PHPSoapClient'
//~mrossw ),
//~mrossw 'socket' => array('bindto' => '158.69.189.149')
'socket' => array('bindto' => '127.0.0.1')
//~mrossw ,
//~mrossw 'ssl' => [
//~mrossw 'verify_peer' => true,
//~mrossw 'verify_peer_name' => true,
//~mrossw 'allow_self_signed' => true
//~mrossw ]
);
$context = stream_context_create($opts);
$client = new SoapClient("https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl",
//~mrossw $client = new SoapClient($doc_root.'OpCotizadorVehiculoExtReqABCS.xml',
array(
'location' => "https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl",
'uri' => "https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones",
// Stuff for development.
'trace' => 1,
'exceptions' => true,
'keep_alive' => true,
'connection_timeout' => 120,
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE,
'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | SOAP_COMPRESSION_DEFLATE,
//~mrossw 'local_cert' => $certRequest_param['sslcertfile'],
//~mrossw 'login'=>'username',
//~mrossw 'password' => 'password'
)
);
} catch (Exception $e) {
echo \"<h2>Exception Error!</h2>\";
echo $e->getMessage();
// print_r($e);
}
The WS provider has an dev environment on port xxxx and a prod env on port yyyy. Hostname and path request are the same.
SoapClient instanciation and operation call work perfect in dev env.
When i change the port to fetch against prod env I get the following error:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl' : failed to load external entity "https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl"
Provider says my public web server's IP is correctly set as allowed in their firewall. It looks right because when I tried to run the code from a different server with different IP and it fails with the same error in both dev and prod env.
When I run that code from a server inside a private network, it works in both
environment ! I don't know much about security, but this sounds to me like a security breach. I mention it here though, in case it can give a clue. I guess this is because this server has a private ip and the provider's firewall don't filter it.
When I go to https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl in my PC browser i get the correct wsdl's xml.
Do you have an idea of what can prevent the code to work form my public web server ?
Or maybe what else can I check ?
For example I couldn't find a way to check the ws server's http response code from outside my browser.
I could neither get a curl request form bash to return the wsdl xml, but that should be another question maybe.
Also let me know if i can provide any other relevant test or data.
My website is https://www.mystylequest.com. We provide answers to fashion related questions like "can I find this dress in Yellow?". Answering a question involves submitting a link to a website with the dress, then my website scraps the neccessary images from the submitted link. However, we keep getting this error: file_get_contents(): SSL: Success upon submitting a valid image link (eg: https://poshmark.com/listing/Blue-and-White-Striped-Palazzo-Pants-5cf5ccaf6a7fbadddcaf2f07).
Here is the code:
if (isset($_POST['SubmitAnswersWithImage'])) {
$image_url = trim($_POST['AnswerImg']);
$url = trim($_POST['AnswerUrl']);
$postId = (int)$_POST['PostId'];
// This is to bypass websites that block our ip
$aContext = array(
'http' => array(
'proxy' => 'tcp://138.68.161.60:8080',
'request_fulluri' => true,
),
);
$cxContext = stream_context_create($aContext);
$image_data = file_get_contents($image_url, false, $cxContext); // Error occurs
$web_url = GoogleStorageManager::uploadBlob('quest_answers', $image_data)->webUrl();
<!-- irrelevant code -->
Any solutions will be greatly appreciated
Thanks in anticipation.
try
// This is to bypass websites that block our ip
$aContext = array(
'http' => array(
'proxy' => 'tcp://138.68.161.60:8080',
'request_fulluri' => true,
),
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
),
);
https://www.php.net/manual/en/migration56.openssl.php
An official document describing the changes made to open ssl in PHP 5.6 From here I learned of one more parameter I should have set to false: "verify_peer_name"=>false
Note: This has very significant security implications. Disabling
verification potentially permits a MITM attacker to use an invalid
certificate to eavesdrop on the requests. While it may be useful to do
this in local development, other approaches should be used in
production.
Statement: At the beginning I would like to state, that I'm well aware (and want to inform others) that this is not the proper way of doing things. If soultion is found, use it as last resort.
My problem is Weak Algorithm. And can't find a way to skip checks.
Company which exposes me endpoint states it is secure and they're not going to upgrade SSL Certificate. I know it's insecure, but can't do anything and must obey their decision.
Error i get file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:14082174:SSL routines:ssl3_check_cert_and_algorithm:dh key too small
and file_get_contents(): Failed to enable crypto in...
My code is:
$context = stream_context_create([
'http' => [
'timeout' => 5,
],
'ssl' => [
// set some SSL/TLS specific options
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
]
]);
var_dump(file_get_contents($wsdl, false, $context));
In browser i ge SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY and information about weak Diffie Hellman key.
I'm looking for a way to disable this check.
Most preferably via streamContext which I can use in SoapClient
You need disable Diffie Hellman validation:
$context = stream_context_create(array(
'ssl' => array(
'ciphers' => 'DEFAULT:!DH',
...
If need disable the validation of the certificate you need:
$context = stream_context_create(array(
'ssl' => array(
'ciphers' => 'DEFAULT:!DH',
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
I have googled and looked here in stackoverflow but I have not found a solution to my specific problem. I keep getting the error
SOAP-ERROR: Parsing WSDL: Couldnt load from "https://sampleurl.com/MerchantQueryService.asmx?WSDL" : failed to load external entity "https://sampleurl.com/MerchantQueryService.asmx?WSDL"
I am trying to use a SOAP API with a URL like
https://sampleurl.com/MerchantQueryService.asmx?WSDL
I am running MAMP on my localhost and using godaddy shared hosting, I have tried on both with the wsdl file can be found here
http://clemdemo.com/test.wsdl
In PHP I use the code below
error_reporting(-1);
ini_set('display_errors', 'On');
ini_set('soap.wsdl_cache_enabled', 0);
echo "<pre>";
try {
$url = "https://sampleurl.com/MerchantQueryService.asmx?WSDL ";
$headers = [
'Host: sampleurl.com',
'Connection: Keep-Alive',
'User-Agent: PHP-SOAP/5.3.29',
'Content-Type: text/xml; charset=utf-8',
'SOAPAction: "RequestTransaction"',
'Content-Length: 409'];
$rq = [
"userName" => "username_here",
"passWord" => "password_here",
"referenceId" => "3455566694",
"msisdn" => "346774313"];
try {
$cient = new SoapClient($url,
[
'soap_version' => SOAP_1_2,
'exceptions' => 1,
'cache_wsdl' => WSDL_CACHE_NONE,
'trace' => 1,
'stream_context' => stream_context_create(array('http' => array('header' => $headers)))
]);
print_r($cient);
} catch (SoapFault $e) {
echo "\nFault Code: ".$e->faultcode;
echo "\nFault String: ".$e->faultstring;
}
On my MAMP localhost i have SOAP,openssl and curl.
ALSO, I tried using (sending request) to the API with an online WSDL http://wsdlbrowser.com it WORKS but on code using PHP it fails
It often happens that providers neglect their SSL certificates and hence the sites and services end up having an invalid certificates - I suspect this is the case here.
Disabling the certificate validation as described by Kaii here or even better get your provider to fix their certificate.
Your code could/should then be something like:
$url = "https://sampleurl.com/MerchantQueryService.asmx?WSDL ";
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
));
$rq = ["userName" => "username_here",
"passWord" => "password_here",
"referenceId" => "3455566694",
"msisdn" => "346774313"];
$service = new SoapClient($url, array('stream_context' => $context));
$service->RequestTransaction($rq);
The error message appears to say that your app is not able to read our WSDL. Try opening a browser from the same machine on which your app is running and see if you can access the WSDL address at https://sampleurl.com/MerchantQueryService.asmx?WSDL.
If not - you have a network/firewall/Anti Virus problem. (in case)
If you can access this address from a browser - is your app still experiencing this problem? then check any app that could be hindering your firewall.(Anti virus are most probable cause)
If you use docker there is a chance you get error because of OpenSSL default security level. Even if you disable verify and allow self-signed in SoapClient options.
Try out to lower seclevel in /etc/ssl/openssl.cnf from DEFAULT#SECLEVEL=2 to
DEFAULT#SECLEVEL=1
Or just add into Dockerfile
RUN sed -i "s|DEFAULT#SECLEVEL=2|DEFAULT#SECLEVEL=1|g" /etc/ssl/openssl.cnf
By: https://github.com/dotnet/runtime/issues/30667#issuecomment-566482876
You can verify it by run on container
curl -A 'cURL User Agent' -4 https://ewus.nfz.gov.pl/ws-broker-server-ewus/services/Auth?wsdl
Better diagnostics can be performed with: libxml_get_last_error();
Could have cached a bad response, set 'cache_wsdl' => WSDL_CACHE_NONE when initating the object
if you skip cache, and get this in your libxml error:
LibXMLError Object
(
[level] => 1
[code] => 1549
[column] => 0
[message] => failed to load external entity "URL"
[file] =>
[line] => 0
)
With no description on Ubuntu, then its not pulling the file period. You just got hit with the Ubuntu update. Wave them the bronx salute and reboot.
I was working with older version of OpenSSL(OpenSSL 0.9.8o) and I was forced to use newer OpenSSL 1.0.1e-fips as the result I was unable to connect to WSDL:
Message: SoapClient::SoapClient(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
I need to disable SSL certification check, I tried:
$client = new SoapClient("https://IP:443/sdk/vimService?wsdl",
array(
"trace" => 1,
"location" => "https://IP:443/sdk/",
"stream_context" => stream_context_create(
array(
'ssl' => array(
'verify_peer' => false,
'allow_self_signed' => true,
)
)
)
)
);
`
And it throw:
Message: SoapClient::SoapClient(): Peer certificate CN=localhost.localdom' did not match expected CN=SAME IP AS IN SoapClient()'
Then I added 'peer_name'=> 'localhost.localdom', in stream_context and then it says XML file is empty:
Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML document
PHP 5.5
Okey, I was able to found issue.
You can avoid this mess using stable PHP 5.5 version
Recently I learned that error: "looks like we got no XML document" is caused because of PHP version - PHP 5.6 in 5.5 working like a charm.
How to fix it in PHP 5.6
1) Remove SSL certificate check in PHP 5.6:
In 5.6 version SSL certification was enabled by default, so if you want to disabled it you must pass context stream:
"stream_context" => stream_context_create(
array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
)
)
)
2) Deleted ?wsdl and added .wsdl instead (with ?wsdl, it didn't worke for me)
<?php
$client = new SoapClient("https://IP:443/sdk/vimService.wsdl",
array(
"trace" => 1,
"location" => "https://IP:443/sdk/",
'exceptions' => 1,
"stream_context" => stream_context_create(
array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
)
)
)
)
);
$soapmsg["_this"] = array( "_" => "ServiceInstance", "type" => "ServiceInstance");
$result = $client->RetrieveServiceContent($soapmsg);
$ServiceContent = $result->returnval;
$soapmsg = NULL;
$soapmsg["_this"] = $ServiceContent->sessionManager;
$soapmsg["userName"] = "USERNAME";
$soapmsg["password"] = "PASSWORD";
$result = $client->Login($soapmsg);
$UserSession = $result->returnval;
echo "User, " . $UserSession->userName . ", successfully logged in!\n";
$soapmsg = NULL;
$soapmsg["_this"] = $ServiceContent->sessionManager;
$result = $client->Logout($soapmsg);
In my case stream_context_create didn't worked.
So I download this file here : https://curl.haxx.se/ca/cacert.pem
and placed it in my localhost as : F:\xampp\apache\cert.pem
and gave the same path for
openssl.cafile=F:\xampp\apache\cert.pem in my phpini
This made the localhost to acquire certificate and things worked great...!!
Posting this in case this may help some one going through my situation.
In my case was needed to add the crypt_method
"stream_context" => stream_context_create(
array(
'ssl' => array(
'verify_peer' => true,
'verify_peer_name' => true,
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
)
)
)
In my case "stream_context" did the magic, i've just added the code :
`"stream_context" => stream_context_create(
array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
)
)
)`