cURL PHP ERROR: Unknown SSL protocol error in connection - php

I'm trying to send an Ajax request using cURL PHP but it gives the error
Unknown SSL protocol error in connection
while I'm able to login to same server.
I've tried this
curl_setopt( $ch, CURLOPT_SSLVERSION, 1 );
and Ajax request is something like that
$header = array('Accept' => '*/*',
"X-Requested-With" => "XMLHttpRequest",
"Content-Type" => "application/x-www-form-urlencoded");
$data = array('ClientNumber=999999&OrderClass=ContractOrders&ShowAll=ContractOrders&ShowPerPage=500');
echo $page = Spider::spider($header, 'https://wfs.nursefinders.com/MasterConsole/displayorders.cfm?ShowAll=ContractOrders', 'https://wfs.nursefinders.com/MasterConsole/BuildOrderDisplaySection.cfm', FALSE, $data[0]);
Note in spider function, first argument is header, second is referrer third is url to access, fourth doesn't matter it's for cookie file and fifth is data o post
I'm using UBUNTU 14.10 and cURL Version is curl 7.37.1 according to this command /usr/bin/curl -V
and same as printing by php phpinfo()
Please help

I believe the reason for your problem is that the server you are communicating with does not support your SSL protocol.
There is a page here with information on that: http://blog.techstacks.com/2010/03/3-common-causes-of-unknown-ssl-protocol-errors-with-curl.html
For more direct information, try looking into the API Documentation for the required connection protocol for their server. They may have provided a sample that will connect.

This server is terrible broken. It does not support the most compatible SSLv23 handshake and will just hang if one tries it. It only supports explicit SSL 3.0 or TLS 1.0 handshakes. From looking at the source code of cURL it seems to me, that all variations of enforcing TLS1.0+ will do a SSLv23 handshake, which the server can not do:
-- curl-7.41.0/lib/vtls/openssl.c
1719 default:
1720 case CURL_SSLVERSION_DEFAULT:
1721 case CURL_SSLVERSION_TLSv1:
1722 case CURL_SSLVERSION_TLSv1_0:
1723 case CURL_SSLVERSION_TLSv1_1:
1724 case CURL_SSLVERSION_TLSv1_2:
1725 /* it will be handled later with the context options */
1726 req_method = SSLv23_client_method();
This leaves only the option of using the insecure SSL 3.0, that is
curl_setopt( $ch, CURLOPT_SSLVERSION, 3 );
While I have no PHP to test with, a short test with curl -1 vs. curl -3 on the command line confirms that CURLOPT_SSLVERSION of 1 will not work while 3 should work.

Related

PHP CURL suddenly stop working on https request

Until literally a couple of days ago, everything was going well, but now, Curl has stopped working for addresses with HTTPS.
This is the code:
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => array($registation_ids),
'data' => array( "message" => $message,
"title" => $title,
"params" => $params,
"code" =>$code),
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
This code had been running smoothly for over a year. But now it returns this:
Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET
/app/test_notifications.
Reason: Error reading from remote server
Apache/2.2.15 (Red Hat) Server at app-servername.rhcloud.com Port 80
However, if in the previous code I remove the s from https:// ... like this http://android.googleapis.com/gcm/send the request is sent without problems, but I can not allow that modification, since I also need access to other addresses that require SSL.
I have also tested with other https addresses, but it is the same result
Searching on the internet I found the solution to update curl, but I'm not sure if that is my solution, since the code executed correctly https requests last week. Anyway I leave here the curl --version response on my server:
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz
Is there a way to test that, in effect, is a Curl problem? That would help me to know how to find the solution.
I think it's a Google upgrade not a Curl problem.
Firebase Cloud Messaging (FCM) is the new version of GCM. It inherits the reliable and scalable GCM infrastructure, plus new features! See the FAQ to learn more. If you are integrating messaging in a new app, start with FCM. GCM users are strongly recommended to upgrade to FCM, in order to benefit from new FCM features today and in the future.
GCM Connection Server Reference
HTTP Protocol
XMPP Protocol
Android API Reference
iOS API Reference
Chrome API Reference
Contents
Downstream message syntax
Downstream HTTP messages (JSON)
Notification payload support
Downstream HTTP messages (Plain Text)
Interpreting a downstream message response
Downstream message error response codes
Check https://developers.google.com/cloud-messaging/http-server-ref
Reviewing the problem and comparing my different applications in Openshift I realized that curl in https addresses worked in one of them. I checked the differences using phpinfo() and discovered that, contrary to what the server indicated, in the application that presented the problem, SSL Version was 3.18.1 and not 3.27.1.
Solution: restart the application in openshift and if that does not work, manually update curl. (Restart work for me)

CentOS PHP curl unable to negotiate an acceptable set of security parameters

On an Ubuntu 14.04.3 this code works fine:
$url_login = "https://test.example.com/login.do";
$cert_file = '/var/www/html/test/cert.pem';
$ssl_key = '/var/www/html/test/cert_private.pem';
$post_fields = 'userAction=1&cancelReason=&cancelType=&account=&memoType=&userText=&userid=99999999&password=xxxxxxxxxxxxxxxx';
$ch = curl_init();
$options = array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HEADER => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
CURLOPT_VERBOSE => 0,
CURLOPT_URL => $url_login ,
CURLOPT_SSLCERT => $cert_file ,
CURLOPT_SSLCERTTYPE, 'PEM',
CURLOPT_SSLKEY => $ssl_key,
CURLOPT_COOKIESESSION => 1,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_fields
);
curl_setopt_array($ch , $options);
$output = curl_exec($ch);
The php on Ubuntu is using curl with openssl.
On a Centos 7 if fails with:
Curl Error : SSL peer was unable to negotiate an acceptable set of security parameters.
curl is here with nss.
The "cert.pem" contains only the client certificate with the cert-chain, and the "cert_private.pem" contains the private key not password protected. (-----BEGIN RSA PRIVATE KEY-----).
How can i get the above PHP code work with both? openssl and nss implementations of curl?
How about correcting:
CURLOPT_SSLCERTTYPE, 'PEM',
to
CURLOPT_SSLCERTTYPE => 'PEM',
?
I've also come across this problem using client certificate authentication with nss, while openssl works fine.
After much testing, this is what I've established with the server we're trying to contact:
curl using TLS v1.2 (default in some cases) with client certificate fails
curl using TLS v1.2 with client cert required by server, but not used by client, connects successfully. However client is not authenticated.
curl using TLS v1.0 with client certificate is successful
The above happens regardless of cipher suite, generally we're using rsa_aes_256_cbc_sha_256.
The quick workaround is to force TLS v1.0:
CURLOPT_SSLVERSION => 4,
Clearly this isn't ideal, and your server may not support it.
Another option is to compile curl with openssl or even GnuTLS (although I haven't tested the latter) instead of nss. Again, this may not be an option.
So far this points to a problem with NSS. I'll update this answer if further debugging generates any useful information.
Just for reference, this is the full error message using curl on the command line:
* NSS error -12227 (SSL_ERROR_HANDSHAKE_FAILURE_ALERT)
* SSL peer was unable to negotiate an acceptable set of security parameters.
* Closing connection 0
curl: (35) SSL peer was unable to negotiate an acceptable set of security parameters.
Update 2015-11-24: Further testing with Wireshark and ssltap shows the initial handshake is succeeding and the connection gets as far as the client sending ChangeCipherSpec, followed by its encrypted "Finished" message.
The server should then decrypt the client's "Finished" message, verify the hash and MAC and respond with its own encrypted "Finished" message. Instead, the server is responding with "handshake_failure" at this point.
This should provide a clue as to where NSS is failing.
Chrome, Openssl and Charles Proxy can all authenticate using the client certificate. Firefox (using NSS) and curl (with NSS) both fail at this point.
Update 2015-11-27: Additional information provided by the server's operations team suggests this may be an issue with a non-compliant server. The problem only arises when using TLS 1.2 under certain circumstances. This would explain why some SSL libraries, such as OpenSSL, are flexible enough to work around it.
NSS may be more strict in its compliance with RFCs. I'll update the answer if/when we hear more from the operations team managing the server.
Update 2017-01-25: The webserver software and load balancers are custom built for a specific bank's payment gateway. We've recently tried again with a new client and the server now appears to work with both Curl built with either NSS or OpenSSL and are no longer seeing the error. In summary: the workaround was to use a different SSL library and wait for the developers to fix the server software.

curl doesn't get site contents on PHP via HTTPS

I have read all the internet and tried almost all solutions, nothing works.
If I run curl http://... site, it works but if i run https://... it doesn't.
I' running centos 7 with php 5.6
Nothing happens also if I try the famous answer with
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
The only thing that can help me getting the site is
curl -4svo/dev/null --ciphers ecdhe_ecdsa_aes_128_sha https://.....
however since i need to send my headers, it is not a solution, i need something compatible with the curl_setopt.
UPDATE ERROR
I get this: curl: (35) Cannot communicate securely with peer: no
common encryption algorithm(s).
i think , this problem is caused by the version of cURL not supporting ECC 256 bit SSL certificates and the ECDSA signature algorithm (which is used by CloudFlare). You can test to see if your version of cURL supports this encryption by running:
curl -1IsS --ciphers ecdhe_ecdsa_aes_128_sha https://sslspdy.com
If you get the following, then your cURL is out of date:
curl: (59) Unknown cipher in list: ecdhe_ecdsa_aes_128_sha
This is the magic line!
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'ecdhe_ecdsa_aes_128_sha');

Using HTTPS link with php methods (file_get_contents, getimagesize)

I get a problem when I try to read some HTTPS url in my website.
If I use "http", there is no problem (with file_get_contents and curl), but when I remplace "http" by "https", these methods don't work.
I get some errors:
failed to open stream: operation failed occured
Failed to enable crypto occured
SSL operation failed with code 1. OpenSSL Error messages: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
In my browser, all methods work:
https://ssl10.ovh.net/~fyprbqhq/_perso/facebook.myclimb/test.php (Display should show "OK")
In phpinfo() I got:
openssl
OpenSSL support enabled
OpenSSL Version OpenSSL 0.9.8c 05 Sep 2006
If you have any ideas.
Thanks for help.
(Ps: get_headers() don't work too with https in my case)
More info:
file_get_contents:
$data = file_get_contents("https://ssl10.ovh.net/~fyprbqhq/_perso/facebook.myclimb/test.php");
Curl:
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, "http://ssl10.ovh.net/~fyprbqhq/_perso/facebook.myclimb/test.php");
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);
$data = curl_exec($curl_handle);
curl_close($curl_handle);
Judging from the error you received (SSL23_GET_SERVER_HELLO:unknown protocol) this is almost certainly caused by the server having a newer version of SSL than your client.
The server is probably using a version >= 1.0.0, while you are using 0.9.8c
Your version of SSL is from 2006. Take a look at the list of vulnerabilities in OpenSSL in the last 5 years, as a reason for you to upgrade.
Lots of other people have reported similar experiences
. Also here and here.
If you're using PHP 5.6.x, there's been some changes that effect SSL/TLS negotiation.
In PHP 5.6, all stream wrappers now verify peer certificates and host names by default when using SSL/TLS.
To work around hosts the have don't have validate ssl / tls sockets, try using this.
$ctx = stream_context_create(['ssl' => [
'capture_session_meta' => TRUE,
'verify_peer' => false,
'verify_peer_name' => false
]]);
$html = file_get_contents('https://google.com/', FALSE, $ctx);
$meta = stream_context_get_options($ctx)['ssl']['session_meta'];
var_dump($meta);
This of course isn't recommended as you are forfeiting the verification of your host.
For me, this came into play while access the flickr api -- api.flickr.com.
Reference: http://php.net/manual/en/migration56.openssl.php

406 "Not Acceptable" error when using JanRain OpenID Library with Google

I am using the latest Janrain openid library example and the discovery process seems to work well with Yahoo, myopenid.com and others...
But I am stuck with Google endpoint (https semicolon //www.google.com/accounts/o8/id). Consumer.php just returns a 406 apache error, before I am redirected to google's page.
All my installation is available here :
http://www.coplango.com/vendor/openid/examples/
Click on consumer to try the consumer example, but discovery.php fails the same way,proving it happens during discovery...
You can also check detect.php to check my installation - The HTTP fetching test fails with a 503 because it tries to reach an address which returns a 503. Rest is fine.
I supposed it was down to php-yadis specifying Accept: application/xrds+xml header but I checked the code and other types are also accepted such text/html and application/xhtml+xml.
Anyone came accross this?
Any clue?
Thank you very much!
Ok,
I have investigated further and it seems to be down to my provider, who returns a 406 error if any string containing the death word "/id" is passed as GET parameter. Took me days to figure out it was not down to openid !!
For info I am using PlanetHoster, if anyone else ever comes accross this. I have sent them a ticket request and waiting for their answer.
running the consumer example at my machine, i get the following error:
Got no response code when fetching https://www.google.com/accounts/o8/id
CURL error (60): SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
this means curl fails verifying google's https server certificate. you can workaround this by either providing curl with CA certificates to verify google's certificate via CURLOPT_CAINFO/CURLOPT_CAPATH, or - easier - stop validating the cert via CURLOPT_SSL_VERIFYPEER. the following change in Auth/Yadis/ParanoidHTTPFetcher.php accomplishes latter for me:
--- ParanoidHTTPFetcher.php.orig 2009-04-22 02:31:20.000000000 +0800
+++ ParanoidHTTPFetcher.php 2009-09-30 22:35:24.093750000 +0800
## -127,6 +127,9 ##
Auth_OpenID_USER_AGENT.' '.$curl_user_agent);
curl_setopt($c, CURLOPT_TIMEOUT, $off);
curl_setopt($c, CURLOPT_URL, $url);
+
+ // don't verify server cert
+ curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_exec($c);
of course, your curl installation must also support ssl - check your phpinfo(). also, if CURLOPT_SSL_VERIFYPEER is disabled, CURLOPT_SSL_VERIFYHOST may also need to be TRUE or FALSE.
see also http://www.openrest.eu/docs/openid-not-completely-enabled-for-google.php (via the Related Why doesn't Google OpenID provider work with PHP-OpenId on my server?).
SOLUTION:
In the .htaccess file put
SecFilterEngine Off

Categories