PHP TCP connection to EPP API using SSL certificate authentication - php

I have tried this upwards and backwards without any success. The national domain registry department has decided to change their entire system to EPP. Their documentation is very poor but to summarize:
Connection via TCP: epptest.ficora.fi port 700
To whitelist for firewall, add IP address and SSL certificate to user account on dashboard (done that)
The dashboard is a total mess. I cannot upload the same certificate to different users, I can't remove users etc. Anyhow, you are supposed to connect to that address and verify yourself using the same SSL certificate in the request (atleast that's what I've understood) but I cannot get it to work. All my requests return:
Error 7: "Failed to connect to epptest.ficora.fi port 700: Timed out"
I've created a login XML based on the documentation which I send out in the POST request.
ini_set('max_execution_time', 300);
set_time_limit(0);
$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_POSTFIELDS, $content);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,0);
curl_setopt($curl, CURLOPT_TIMEOUT, 400);
curl_setopt($curl, CURLOPT_SSLCERT, __DIR__ . '/certificate.crt');
$output = curl_exec($curl);
echo 'Error ' . curl_errno($curl) . ': "' . curl_error($curl) .'"';
curl_close($curl);
The certificate file can be found, I did a file_get_contents() test and reads OK. This is a localhost test on a Windows computer.
Testing the same code on my own (live) server I get:
Error 56: "Recv failure: Connection reset by peer"
I don't know if this sounds stupid or not but does the request have to originate from a server, from an address, where the SSL certificate is in use?
I am at a complete loss with this as to why it doesn't work. Help, anyone?
EDIT
Here's the cURL verbose information:
* About to connect() to epptest.ficora.fi port 700 (#0)
* Trying <ip_address>
* connected
* Connected to epptest.ficora.fi (<ip address>) port 700 (#0)
> POST / HTTP/1.1
Host: epptest.ficora.fi:700
Accept: */*
Content-type: text/xml
Content-length: 146
* upload completely sent off: 146 out of 146 bytes
* additional stuff not fine transfer.c:1037: 0 0
* Recv failure: Connection reset by peer
* Closing connection #0

The answer in the end came to me through another Stackoverflow post. I actually didn't have the private key in the certificate so what I had to do was create a new .pem file (just plain text in any editor) and paste the private key and certificate in it like so:
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE----
-----END CERTIFICATE-----
The certificate is supposed to have the key in it. All I had was them separate. No one actually pointed this out.
HOWEVER! I was not able to make this work in cURL. The response I got was through a PHP-EPP library that uses stream_socket_client() function.

I've seen two kinds of errors from epptest.ficora fi:
Connection timeout indicates the IP address is not allowed to connect.
Connection reset by peer indicates the certificate is invalid.
This weekend all my connections failed with Connection reset by peer. Today (29.8.2016) it started working again, so this was probably a temporary issue. So far I have seen successful authentication with CAcert server certificates and Comodo FreeSSL certificates.
However, an IP address that I enabled two days ago is still blocked. It's possible that their automatic firewall updating every 8 hours is not working as documented and that you'll need to contact Ficora support (fi-domain-tech#ficora.fi) to open the IP.
Also, I don't believe curl supports EPP, so it's probably not useful in this case. (EPP is a custom protocol used over TCP port 700. It's not based on HTTP.)

Related

PHP CURL error: SSL certificate problem: unable to get local issuer certificate

I have looked at every solution listed on STACKOVERFLOW. Nothing resolves this issue. The issue I am having is only when I attach a port, in this example 5443, to the cURL PHP code. If I do a CLI without the port it works. In Code, if I do just a straight URL https://HOSTNAME/api/test without assigning a port, it works. Either way I can see the GET come in. This is all about certification verification. The port is open on the server.
I have a GoDaddy G2 certificate. I have a newly built server with a CA-bundle and I have tried using the root certificate, the certificate bundle from
"https://curl.haxx.se/docs/caextract.html"
and every other combination. I always get the same error when I add in the port number:
"SSL certificate problem: unable to get local issuer certificate"
$url = "https://HOSTNAME/api/test";
$curl = curl_init();
if ($curl === false)
{
echo "Failure";
} else
{
curl_setopt($curl, CURLOPT_PORT, 5443);
curl_setopt($curl, CURLOPT_HTTPGET, true);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// Turn on SSL certificate verification
curl_setopt($curl, CURLOPT_CAPATH, "/fully_resolved_path/");
// and tried this way too
curl_setopt($curl, CURLOPT_CAPATH, "/fully_resolved_path");
// tried this
curl_setopt($curl,CURLOPT_CAINFO,"/fully_resolved_path/cacert.pem");
// This is actually the default setting, 1 no longer supported, and has no effect on the final result in this case.
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
// fails when this is TRUE! Performs no checking when FALSE
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, TRUE);
$result = curl_exec($curl);
if ($result === false)
{
echo curl_error($curl);
} else
{
echo $result;
}
curl_close($curl);
}
Everything is set up and works as expected, returns a JSON object. Only when I add in the Port Number does it choke. The Common Name in the SSL Certificate Matches the HOSTNAME. As stated, it works until I add in a port number.
I have looked at every solution listed on STACKOVERFLOW. Nothing resolves this issue.
Wow. But unfortunately this "information" is useless since it does not say anything of what you actually tried.
The issue I am having is only when I attach a port, in this example 5443, to the cURL PHP code. If I do a CLI without the port it works.
This because without port it will use port 443. Since you explicitly use port 5443 you connect to a different server with a different setup and which provides different certificates compared to the one on port 443. Just try to set the port explicitly to 443 and you'll see that it works.
It is likely that the server on port 5443 is providing some self-signed certificate, some certificate issued by some unknown CA or is missing the necessary chain certificates (i.e. misconfigured). These are the causes usually associated with this kind of error and you should have seen this already and also seen the solutions since you "looked at every solution listed on STACKOVERFLOW". Only remember that to fix you need to look the server at port 5443 and not the default server at port 443.

Access Web Service through PHP using Navision User (SSL Enabled) Authenthication

I need to access the Web Service of Navision that is using Navision User + SSL. The connector I am using is based in PHP.
I am able to connect to simple http access and using Window's User. This is the tutorial that helped me achieve this Navision Web Service PHP written by Freddy.
I'm still using it but played around on adding the certificate in the curl/request. Researched and read a lot of article but I still cannot achieve it.
I am now able to access it using the base php connector shared above (link) but when retrieving data I am receiving the details below:
... successfully set certificate verify locations:
* CAfile: /Path/Navision.pem
* SSL connection using TLSv1.0 / AES256-SHA
* Server certificate:
...
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* Server auth using NTLM with user 'user'
POST Navision Page URL Name HTTP/1.1
Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
...
Method: POST
Connection: Keep-Alive
User-Agent: PHP-SOAP-CURL
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:microsoft-dynamics-schemas/page/pda_item_list:ReadMultiple"
...
< HTTP/1.1 401 Unauthorized ...
I used the certificate by using the makecert.exe. I have these files 2 .cer, a pvk and a .crl.. We used one of the .cer file took the thumbprint to apply it on the navision service instance. Which of the file is the correct one to be used by the php curl connector.
Here is my request php code:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_USERPWD, USERPWD);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/Navision.pem');
Any link that is related would be much appreciated specially if I'll be able to use the web service of Navision using PHP connector by accessing it using Navision User and SSL.
UPDATE
I am now able to use the valid certificate and able to pass through properly.
Still it doesn't now work and returns the the same error above.. Unauthorized 401.
Most likely it is because of my Navision setup or I am just passing the credentials in a wrong way? I am still researching and playing so currently I am still not able to pull the data.
you have two options :
have second service tier which is using Username authentication. This will enable PHP to use Basic Auth. You'll need a cert in this case
the second option is to use the same service tier but generate a Web Service Key for the use what the PHP is using. You can use Basic Auth using the same Username but using the Web Service Key as password
PHP is not a fan of NTLM authentication...
Cheers

HTTP Basic Authentication combined with SSL/TLS (HTTPS) will be used to authenticate user

i need to send json request (RESTful) to a URL where the server authority send me the username & password and ask me to send the request to the server using "HTTP Basic Authentication combined with SSL/TLS (HTTPS) will be used to authenticate user".
when i send the request to that link using cURL then i get the error.
"Error: call to URL failed with status 0, curl_error SSL certificate problem: self signed certificate, curl_errno 60"
My Web server version is: IIS7, PHP Version: 5.3.27.
Now, what is the process to complete the task. please help.
This is not a problem with HTTP Basic Auth but with certificate You've generated for Your server, which is not signed.
If it's You dev server You can switch off SSL verification
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
In case it's production You have to sign Your certificate with proper CA.

cURL SSL Certificate error "Bad Certificate"

I'm trying to send an SSL certificate with a soap message to a server and have only just managed to make cURL accept the certificate (.pem file spit out by putting a .pfx file through OpenSSL) and not return "unable to set private key file" (evidently the private key must keep its 'bag attributes'), however it's now returning exciting new errors:
SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
I've tried setting the CA certificate with:
curl_setopt($soap_do, CURLOPT_CAINFO, $caFile);
But this yields no results with the root nor the intermediate ca files I have.
Disabling this check with:
curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, 0);
brings me to the new problem:
error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate
This has been a thorn in my side for weeks now and while new error messages mean changes I'm not sure it means progress. Any advice or suggestions as to what is missing/I am doing wrong would be greatly appreiciated.
most likely the CA bundle is wrongful. verify the path & access permissions, maybe try setting an absolute path. if this not helps, get a CA bundle and set it alike curl_setopt($soap_do, CURLOPT_CAINFO,'cacert.pem');
sslv3 alert bad certificate means that CA information is missing. Use --cacert parameter and add CA cert.
unable to set private key file means that certificate passed as --cert is not the public key matched to private key

CURL ERROR: Recv failure: Connection reset by peer - PHP Curl

I'm having this strange error, CURL ERROR: Recv failure: Connection reset by peer
This is how it happens, if I did not connect to the server and all of a sudden trying to connect to the server via CURL in PHP I get the error. When I run the CURL script again the error disappears and then works well the whole time, if I leave the remote server idle for about 30mins or reboot the remote server and try to connect again, I get the error again. So it seems like the connection is idle and then all of sudden the server wakes up and then works and then sleeps again.
This is how my CURL script looks.
$url = Yii::app()->params['pdfUrl'];
$body = 'title='.urlencode($title).'&client_url='.Yii::app()->params['pdfClientURL'].'&client_id='.Yii::app()->params['pdfClientID'].'&content='.urlencode(htmlentities($content));
$c = curl_init ($url);
$body = array(
"client_url"=>Yii::app()->params['pdfClientURL'],
"client_id"=>Yii::app()->params['pdfClientID'],
"title"=>urlencode($title),
"content"=>urlencode($content)
);
foreach($body as $key=>$value) { $body_str .= $key.'='.$value.'&'; }
rtrim($body_str,'&');
curl_setopt ($c, CURLOPT_POST, true);
curl_setopt ($c, CURLOPT_POSTFIELDS, $body_str);
curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 0);
curl_setopt ($c, CURLOPT_TIMEOUT , 20);
$pdf = curl_exec ($c);
$errorCode = curl_getinfo($c, CURLINFO_HTTP_CODE);
$curlInfo = curl_getinfo($c);
$curlError = curl_error($c);
curl_close ($c);
I'm totally out of ideas and solutions, please help, I'll appreciate it!!!
If I verbose the output to see what happens using
curl_setopt ($c, CURLOPT_VERBOSE, TRUE);
curl_setopt($c, CURLOPT_STDERR, $fp);
I get the following
* About to connect() to 196.41.139.168 port 80 (#0)
* Trying 196.x.x.x... * connected
* Connected to 196.x.x.x (196.x.x.x) port 80 (#0)
> POST /serve/?r=pdf/generatePdf HTTP/1.1
Host: 196.x.x.x
Accept: */*
Content-Length: 7115
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue
* Recv failure: Connection reset by peer
* Closing connection #0
012 20:23:49 GMT
< Server: Apache/2.2.15 (CentOS)
< X-Powered-By: PHP/5.3.3
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=UTF-8
<
* Closing connection #0
I've added in the following toe remove the default header and still no luck:
curl_setopt ($c, CURLOPT_HTTPHEADER, array( 'Expect:' ) );
> Accept: */* Content-Length: 8414 Content-Type:
> application/x-www-form-urlencoded
>
> * Recv failure: Connection reset by peer
> * Closing connection #0 r: Apache/2.2.15 (CentOS) < X-Powered-By: PHP/5.3.3 < Connection: close < Transfer-Encoding: chunked <
> Content-Type: text/html; charset=UTF-8 <
> * Closing connection #0
Introduction
The remote server has sent you a RST packet, which indicates an immediate dropping of the connection, rather than the usual handshake.
Possible Causes
A. TCP/IP
It might be a TCP/IP issue you need to resolve with your host or upgrade your OS most times connection is closed with remote server before it finished downloading the content resulting in Connection reset by peer.....
B. Kernel Bug
Note that there are some issues with TCP window scaling on some Linux kernels after v2.6.17. See the following bug reports for more information:
https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.17/+bug/59331
https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.20/+bug/89160
C. PHP & CURL Bug
You are using PHP/5.3.3 which has some serious bugs too ... I would advise you to work with a more recent version of PHP and CURL
https://bugs.php.net/bug.php?id=52828
https://bugs.php.net/bug.php?id=52827
https://bugs.php.net/bug.php?id=52202
https://bugs.php.net/bug.php?id=50410
D. Maximum Transmission Unit
One common cause of this error is that the MTU (Maximum Transmission Unit) size of packets travelling over your network connection has been changed from the default of 1500 bytes.
If you have configured a VPN this most likely must changed during configuration
D. Firewall: iptables
If you don't know your way around these guys they can cause some serious issues .. try and access the server you are connecting to check the following
You have access to port 80 on that server
Example
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT`
The Following is at the last line not before any other ACCEPT
Example
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
Check for ALL DROP, REJECT and make sure they are not blocking your connection
Temporary allow all connection as see if it foes through
Experiment
Try on a different server or on a remote server ( So many free cloud hosting online) and test the same script. If it works then my guesses are correct ... You need to update your system
Others Code Related
A. SSL
If Yii::app()->params['pdfUrl'] is a url with https not including proper SSL settings can also cause this error in old version of curl
Resolution: Make sure OpenSSL is installed and enabled then add this to your code
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);
Normally this error means that a connection was established with a server but that connection was closed by the remote server. This could be due to a slow server, a problem with the remote server, a network problem, or (maybe) some kind of security error with data being sent to the remote server but I find that unlikely.
Normally a network error will resolve itself given a bit of time, but it sounds like you’ve already given it a bit of time.
cURL sometimes having issue with SSL and SSL certificates.
I think that your Apache and/or PHP was compiled with a recent version of the cURL and cURL SSL libraries plus I don't think that OpenSSL was installed in your web server.
Although I can not be certain However, I believe cURL has historically been flakey with SSL certificates, whereas, Open SSL does not.
Anyways, try installing Open SSL on the server and try again and that should help you get rid of this error.
I faced same error but in a different way.
When you curl a page with a specific SSL protocol.
curl --sslv3 https://example.com
If --sslv3 is not supported by the target server then the error will be
curl: (35) TCP connection reset by peer
With the supported protocol, error will be gone.
curl --tlsv1.2 https://example.com
So what is the URL that Yii::app()->params['pdfUrl'] gives? You say it should be https, but the log shows it's connecting on port 80... which almost no server is setup to accept https connections on. cURL is smart enough to know https should be on port 443... which would suggest that your URL has something wonky in it like: https://196.41.139.168:80/serve/?r=pdf/generatePdf
That's going to cause the connection to be terminated, when the Apache at the other end cannot do https communication with you on that port.
You realize your first $body definition gets replaced when you set $body to an array two lines later? {Probably just an artifact of you trying to solve the problem} You're also not encoding the client_url and client_id values (the former quite possibly containing characters that need escaping!) Oh and you're appending to $body_str without first initializing it.
From your verbose output we can see cURL is adding a content-length header, but... is it correct? I can see some comments out on the internets of that number being wrong (especially with older versions)... if that number was to small (for example) you'd get a connection-reset before all the data is sent. You can manually insert the header:
curl_setopt ($c, CURLOPT_HTTPHEADER,
array("Content-Length: ". strlen($body_str)));
Oh and there's a handy function http_build_query that'll convert an array of name/value pairs into a URL encoded string for you.
All this rolls up into the final code:
$post=http_build_query(array(
"client_url"=>Yii::app()->params['pdfClientURL'],
"client_id"=>Yii::app()->params['pdfClientID'],
"title"=>$title,
"content"=>$content));
//Open to URL
$c=curl_init(Yii::app()->params['pdfUrl']);
//Send post
curl_setopt ($c, CURLOPT_POST, true);
//Optional: [try with/without]
curl_setopt ($c, CURLOPT_HTTPHEADER, array("Content-Length: ".strlen($post)));
curl_setopt ($c, CURLOPT_POSTFIELDS, $post);
curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 0);
curl_setopt ($c, CURLOPT_TIMEOUT , 20);
//Collect result
$pdf = curl_exec ($c);
$curlInfo = curl_getinfo($c);
curl_close($c);
This is a firewall issue, if you are using a VMware application, make sure the firewall on the antivirus is turned off or allowing connections.
If this server is on a secure network, please have a look at firewall rules of the server.
Thanks
Ganesh PNS
In my case there was problem in URL. I've use https://example.com - but they ensure 'www.' - so when i switched to https://www.example.com everything was ok. The proper header was sent 'Host: www.example.com'.
You can try make a request in firefox brwoser, persist it and copy as cURL - that how I've found it.
We had the same issue, in making a websocket connection to the Load Balancer.
The issue is in LB, accepting http connection on port 80 and forwarding the request to node (tomcat app on port 8080).
We have changed this to accept tcp (http has been changed as 'tcp') connection on port 80.
So the first handshake request is forwarded to Node and a websocket connection is made successfully on some random( as far as i know, may be wrong) port.
below command has been used to test the websocket handshake process.
curl -v -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: localhost" -H "Origin: http://LB URL:80" http://LB URL
Rebuilt URL to: http:LB URL/
Trying LB URL...
TCP_NODELAY set
Connected to LB URL (LB URL) port 80 (#0)
GET / HTTP/1.1
Host: localhost
User-Agent: curl/7.60.0
Accept: /
Connection: Upgrade
Upgrade: websocket
Origin: http://LB URL:80
Recv failure: Connection reset by peer
Closing connection 0
curl: (56) Recv failure: Connection reset by peer

Categories