Rcls Rcls - 3 months ago 76
PHP Question

PHP stream_socket_client vs. cURL in TCP SSL

I have a problem using

cURL
to POST XML to a TCP address with SSL. I have to pass an SSL certificate in the request which contains the private key + certficate to verify myself.

I just ran a test with a library using
stream_socket_client()
and it uses the
stream_context_set_option
to add an option
local_cert
in which it passes the certificate. Now I can get myself verified using this method, but I cannot do it in cURL. All I get is a
connection reset by peer
error which means the certificate verification failed. What's the difference? Do I have to abandon cURL because it would be (in my opinion) a much cleaner solution.

$content
is valid XML.

$headers = [
"Content-type: text/xml",
"Content-length: " . strlen($content),
"Connection: close",
];

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, 'epptest.ficora.fi');
curl_setopt($curl, CURLOPT_PORT, 700);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSLCERT, __DIR__ . '/certificate.pem');
curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');

$output = curl_exec($curl);

echo 'Error ' . curl_errno($curl) . ': "' . curl_error($curl) .'"';

var_dump($output);


cURL verbose:

* Rebuilt URL to: epptest.ficora.fi/
* Hostname in DNS cache was stale, zapped
* Trying 87.239.122.59...
* Connected to epptest.ficora.fi (87.239.122.59) port 700 (#0)
> POST / HTTP/1.1
Host: epptest.ficora.fi:700
Accept: */*
Content-type: text/xml
Content-length: 406
Connection: close

* upload completely sent off: 406 out of 406 bytes
* Recv failure: Connection was reset
* Closing connection 0

Answer
curl_setopt($curl, CURLOPT_URL, 'epptest.ficora.fi');

You URL does not contain a method like http:// or https://. In this case cURL assumes http:// only and tries to connect directly to the server, i.e. without a SSL handshake. This can be clearly seen from the verbose cURL output. To fix this use a correct URL, i.e. use the correct method at the start of the URL.