Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connecting to https host with soapclient: how to fix SSL problems? [closed]

TLDR

I can't seem to connect to a https endpoint with a SoapClient. As my wget returns a handshake failure, I suspect that is the cause.

How can I do a SOAP request to this server with PHP?

complete

I'm trying to connect to a SOAP server (https). It doesn't have client certificate authentication, so the connection should be pretty straightforward, but sadly it isn't.

The problem is that I keep getting Could not connect to host messages.

The connection method I'm using is working for another server and I've verified that I'm setting the location for this server correctly (changed it to a server I control, and I'm getting response there). I suspect the problem is with the https/ssl connection to the server.

Situation

  • I'm creating a PHP Soapclient based on a wsdl I have locally.
  • If I change the endpoint I get Request and Response headers, and everything works as expected.
  • the machine is reachable from my server, though there is a problem visible when I use wget to connect to it (see below) Unable to establish SSL connection.
  • The problem is also visible with openssl connections (see below)

What I tried.

There are a lot of topics about "no connection!", but there is obviously a lot of "my router was bad, I made a typo in the address etc" going on. I did try these settings that were suggested multiple times, but more as a "cut'n'paste" solution to be sure It didn't work" then out of real reasoning. Some comments from me added

Creating a stream_context for the wsdl options. I have tried

$context = stream_context_create(
              array(
                'ssl' => array(
                           'verify_peer' => false,  //default
                           'allow_self_signed' => true, //needs verify peer, tried that
                           'ciphers'=>"SHA1", // quite random.
                   ),
                'https' => array(
                           'curl_verify_ssl_peer'  => false,
                           'curl_verify_ssl_host'  => false
                          )
      )
            );
$options['stream_context'] = $context;

(first only the ssl options with verify_peer and allow_self_signed. Then I added the https array, then finally I added the ciphers key to ssl.)

I found a reference to this bug, but 1) I'm not getting that warning, 2) it seems to be proxy-related and 3) My version shouldn't have the bug anymore. I'm running php 5.3.10

When I try to wget the url, I get:

    wget https://[[servername]]/SOAP
    Resolving [[servername]] ([[servername]])... xxx.xxx.xxx.xxx
    Connecting to [[servername]]([[servername]])|xxx.xxx.xxx.xxx|:443... connected.
    OpenSSL: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

If I try to connect with openssl, I get this:

$ openssl s_client -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:unknown state
SSL3 alert read:fatal:handshake failure
SSL_connect:error in unknown state
3074463944:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:724:

but if I force ssl3, I get an expected result

$ openssl s_client -ssl3 -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:SSLv3 read server hello A
**happy certificate stuff. this is good**
Protocol  : SSLv3
Cipher    : DHE-RSA-AES256-SHA
**more happy certificate stuff. **

I have tried to add the curl-wrapper from this question with ssl_version set to 3 (as this seems to work on the openssl command above). That wrapper does discard some of the parameters, so I'm not sure how complete this would be. Further, I still get a handshake error, unless I explicitly set checking to false. If I do that (see below), I get an empty response.

curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);

Causes

As said above, I suspect the ssl handshake, but I have no clue how to fix it. I don't suspect issues with the wsdl or the client-creation, as the connection does work with another wsdl, the same wsdl with a different location set etc. It is purely this (https) endpoint that's giving me headaches.

Extra tests.

Just as the test above with the curl wrapper I tried sending a minimal soap envelope as @halfwarr seemed to suggest in the comments. Als returns an empty response.

So with above it seems that I do have a method to squeeze an http 204 out of the server, but that's hardly success. But it could be a second problem? Not sure.

I am supposing that I need to try and force the ssl3, but I have no idea how (and this could be the wrong path as well so I'm trying to not have an XY problem here :)

like image 488
Nanne Avatar asked Jun 05 '13 09:06

Nanne


2 Answers

Interesting. Try adding this:

wget https://[[SERVER]]/soap/ —post-file=request.xml —header=”Content-Type: text/xml” -O response.xml

This will save the result as a file named response.xml.

like image 96
Matheno Avatar answered Oct 21 '22 10:10

Matheno


The latest version PHP 5.5.3 will allow you to set the SSL Version. I've seen others that have been able to use a stream_context but, I was unable to get that work as well.

As a work around and fail safe, I used a catch to grab the soap envelope request (similar to what you tested above):

$xml = $client->__getLastRequest()

and send via curl:


curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

That's allowing me to at least move forward.

like image 33
rdizzle Avatar answered Oct 21 '22 11:10

rdizzle