PayPal TLS Test URL - PHP curl SSL protocol error - php

I'm trying to test against a new PayPal test endpoint: https://tlstest.paypal.com.
See the very bottom of this page: TLS 1.2 and HTTP/1.1 Upgrade Microsite (Verify your...).
I'm using PHP (5.3.28) and curl (7.30.0 - OpenSSL/0.9.8y - libssh2/1.4.2) on Windows Server 2008 R2 and IIS 7.5:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://tlstest.paypal.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_SSLVERSION, 6); // CURL_SSLVERSION_TLSv1_2
$result = curl_exec($ch);
echo 'result = '.$result.'<br>';
echo 'errno = '.curl_errno($ch).'<br>';
echo 'error = '.curl_error($ch).'<br>';
curl_close($ch);
I'm getting this error:
35 Unknown SSL protocol error in connection to tlstest.paypal.com:443
I found this: Github - Unknown SSL protocol error in which someone says:
Openssl must be at 1.0.1 or higher for TLS 1.2.
Is this correct..?
My PHP OpenSSL is on version: OpenSSL/0.9.8y (from phpinfo()).
If you do need OpenSSL 1.0.1 or higher to use TLS 1.2 then presumably every server running PHP with a lesser OpenSSL version (I'm guessing that's a lot!) will be unable to use any PayPal API's or the PayPal IPN soon.
How do I update my PHP OpenSSL version on Windows..?

I have this working now. It seems as though at least OpenSSL/1.0.1i is required for TLS 1.2.
I upgraded my PHP version to 5.6.0, which upgraded OpenSSL to version 1.0.1.
I also needed these:
Use curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); to verify the certificate. The default is true as of cURL 7.10.
Save cacert.pem from http://curl.haxx.se/docs/caextract.html locally (in my case to c:\cert), then update the PHP ini that you're using to reference cacert.pem as shown here. Using the ini file saves you having to use curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '\cacert.pem'); in every call.

Related

PHP CURL - cURL error 35: error:1414D172:SSL routines:tls12_check_peer_sigalg:wrong signature type

I want to make a curl request in PHP 7.3.90
curl -V
curl 7.64.0 (x86_64-pc-linux-gnu) libcurl/7.64.0 OpenSSL/1.1.1d zlib/1.2.11 libidn2/2.0.5 libpsl/0.20.2 (+libidn2/2.0.5) libssh2/1.8.0 nghttp2/1.36.0 librtmp/2.3
Release-Date: 2019-02-06
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL
$ch = curl_init();
// 2. set the options, including the url
curl_setopt($ch, CURLOPT_URL, "https://mydomain/get-token");
curl_setopt($ch, CURLOPT_HTTPHEADER, array("App-Key: YOUR-KEY-HERE"));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0);
and the answer is
"cURL error 35: error:1414D172:SSL routines:tls12_check_peer_sigalg:wrong signature type (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)"
I had the same problem with curl command and i solved it with
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT#SECLEVEL=1
instead of
[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT#SECLEVEL=2
https://github.com/curl/curl/issues/4097 and OpenSSL v1.1.1 ssl_choose_client_version unsupported protocol
Which curl option i have to use to solve this error?
Thanks
I know this questions is quite old but i ran into the same issue when working with some old coughhermescaugh api.
I also did not wanted to set seclevel to 1 for the whole system.
What you are looking for is the following:
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'DEFAULT#SECLEVEL=1');
just put that piece of code into your application and you should be fine for this one request.
Of course this is not the safest way, but when the Api does not set up properly you do not have a choice.
I just had this issue after upgrading from OpenSSL 1.1.0 to 1.1.1 on Debian.
I found the solution here https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=900984
Replace SECLEVEL 2 with SECLEVEL 1 in /etc/ssl/openssl.cnf as SECLEVEL 2 prevents SHA1 encryption, which was necessary for Moneris in my case, which only seems to support the deprecated SHA1 signatures.
After an upgrade on Ubuntu 20, I get the same problem.
The solution was to upgrade to openssl-1.1.1g . By default Ubuntu 20 use the openssl-1.1.1f that don't work well.
link to an installation solution for this still unpackaged version of openssl.
Simply setting DEFAULT#SECLEVEL to 1 didn't work because I needed to fix that issue on Ubuntu 20.04.3 LTS using OpenSSL 1.1.1f 31 Mar 2020.
The solution I found at https://askubuntu.com/a/1233456/306766 worked for me.
You need to add this to the beginning of your config file
(/etc/ssl/openssl.cnf):
openssl_conf = default_conf
And then this to the end:
[ default_conf ]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect] MinProtocol = TLSv1.2 CipherString =
DEFAULT:#SECLEVEL=1
After install Ubuntu 22.04, this issue happened to me and with Replace SECLEVEL 2 with SECLEVEL 0 in
/etc/ssl/openssl.cnf
has been fixed.
Zero is important.

PHP cURL: enforce low TLS version

Goal is to write PHP code testing for TLS v1.2 connectivity. Getting a successful answer isn't a problem, but I can't produce a failure by using an older TLS version in PHP. Testing failures is obviously needed to prove correctness of code (to some reasonable degree).
On the command line I could come up with this, giving a clear distinction:
$ curl -X POST https://api.paypal.com/v1/oauth2/token
{"name":"AUTHENTICATION_FAILURE", [...]
$ curl --tls-max 1.1 -X POST https://api.paypal.com/v1/oauth2/token
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
In PHP I tried this ...
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.paypal.com/v1/oauth2/token');
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
// $response: '{"name":"AUTHENTICATION_FAILURE", [...]
... which means a succcessful TLS v1.2 connection, as one can see in the CLI example above, despite TLS v1.1 being requested. It's the same result as when requesting CURL_SSLVERSION_TLSv1_2.
This is PHP 7.3.7 with cURL 7.64.0 and I hope I can get away without recompiling PHP just for disabling TLS v1.2 support.
To answer my own question, documentation at https://www.php.net/function.curl-setopt is/was outdated. cURL 7.54 changed behavior of CURL_SSLVERSION_ macros, these set now the minimum acceptable TLS version for the connection. It also introduced CURL_SSLVERSION_MAX_ macros, which set the maximum TLS version tried. Until PHP documentation is updated, see https://curl.haxx.se/libcurl/c/CURLOPT_SSLVERSION.html.
Accordingly, limiting the connection to TLS v1.1 works like this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.paypal.com/v1/oauth2/token');
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
Little PHP/CURL test script:
<?php
echo 'PHP version: ' . phpversion() . PHP_EOL;
echo 'cURL version: ' . curl_version()['version'] . PHP_EOL;
$ch = curl_init('https://www.howsmyssl.com/a/check');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0); // TLS 1.0
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1); // TLS 1.1
//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); // TLS 1.2 or 1.3
$data = curl_exec($ch);
curl_close($ch);
$json = json_decode($data);
echo ($data ? $json->tls_version : 'curl request failed') . PHP_EOL;
"TLS v1.1 being requested" is wrong given that TLS v1.1 or later (Added in 7.34.0) is pretty clear as well as "The maximum TLS version can be set by using one of the CURL_SSLVERSION_MAX_ macros"

PHP Curl HTTPS SSL23_GET_SERVER_HELLO:tlsv1

I'm not able to access via curl to a https site and I'm stuck.
The url can be opened in the browser and is using the following secure connection:
The connection to this site is encrypted and authenticated using a
strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA with
P-256), and a strong cipher (AES_128_GCM).
Here the php cUrl script I'm using:
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL,$Org_Input); //$Org_Input
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3');
curl_setopt($curl, CURLOPT_AUTOREFERER, true); //updates the referrer
curl_setopt($curl, CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_SSLVERSION, 6);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,0);
$response= curl_exec($curl);
if (FALSE === $response) {
echo "cUrl Error: " . curl_error($curl) . "<br><br>";
}
The script worked previously with the http url and now causes a problem if the url gets redirected to https. I believe it's linked to curl_setopt($curl, CURLOPT_SSLVERSION, 6);
I tried with the script
for($i=0;$i<=6;$i++) {
//if($i==2) continue;
$ch = curl_init($Org_Input);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSLVERSION, $i);
if(curl_exec($ch) === false)
echo $i.': ' . curl_error($ch) . "<br>";
else
echo $i.': works<br>';
echo "\n";
curl_close($ch);
}
And I get the following error messages:
0: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
1: error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version
2: Unknown SSL protocol error in connection to www.example.com:443
3: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
4: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
5: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
6: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
As the website is using "TLS 1.2" for secure connection I believe the 6 is the right value as it stands for "CURL_SSLVERSION_TLSv1_2"
But then I'm stuck with the error response: "1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version"
Somebody has any idea what could be the issue?
cUrl Version: 7.21.0
Open SSL version: OpenSSL 0.9.8q 2 Dec 2010
openssl version number: 9470239
OpenSSL 0.9.8q 2 Dec 2010
This no longer supported version of OpenSSL does not support modern protocols (TLS 1.2) and modern ciphers. Additionally it might be that the site requires the TLS SNI extension which maybe is not supported by old software.
It is unknown what exactly of these mentioned problem is really the issue since the URL of the site you reach is unknown. But I'm pretty sure that this is one of these causes and that an upgrade of OpenSSL, curl and the PHP bindings for it will solve the problem.
As the website is using "TLS 1.2" for secure connection I believe the 6 is the right value as it stands for "CURL_SSLVERSION_TLSv1_2"
Since this version of OpenSSL does not support TLS 1.2 trying to use TLS 1.2 using this setting will not solve the problem but maybe make it worse. Try to use TLS 1.0 instead since that is the most this OpenSSL version can do.

cURL Error : Cannot connect: SSL is disabled. Error number 35

I am working on the paypal ipn script in one of my applications hosted on a Digital Ocean's box with Centos 7.
When i try to connect to the paypal sandbox api i get the error "Cannot connect: SSL is disabled."
I have tried several things like adding the path of the curl.cainfo in my php.ini file like so
curl.cainfo = /etc/pki/tls/certs/ca-bundle.trust.crt
this is what my cURL script looks like
// STEP 2: Post IPN data back to paypal to validate
$ch = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr'); // change to [...]sandbox.paypal[...] when using sandbox to test
curl_setopt($ch, CURLOPT_SSLVERSION, 4);
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'ecdhe_rsa_aes_128_gcm_sha_256');
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
I have not got much experience with Linux server setup so I am learning as i go along.
Any help or guide is much appreciated
UPDATE : when i run the this command in the command line
curl --version https://sandbox.paypal.com/cgi-bin/webscr
i get this error
curl: (1) Protocol "https" not supported or disabled in libcurl
Also the command curl --version
displays curl 7.42.1 (x86_64-unknown-linux-gnu) libcurl/7.46.0
So i am guessing the new question would be how to enable https in libcurl?
You're setting the wrong SSL version:
curl_setopt($ch, CURLOPT_SSLVERSION, 4);
The Paypal sandbox only supports TLS 1.2 (which is CURLOPT_SSLVERSION == 6). The correct SSL version will be used automatically if you use PHP 5.5.19+ and OpenSSL 1.0.1+, or you can force it yourself with the following (still requires OpenSSL 1.0.1+):
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
I would only expect to see Protocol "https" not supported or disabled in libcurl if this were running a libcurl not installed from rpm - or if whoever configured the machine deliberately broke it for a valid reason, or was very incompetent; the Centos 7 rpm for libcurl has openSSL as a requirement.
Understanding what happened here and remediation will require root access to the target host to install software. You didn't say what access you have on the target system, and you are presumably paying Digital Ocean for support. Unless you broke it yourself, you should be asking Digital Ocean to fix it.
I was able to solve this problem with the help of one my friends with a lot of Linux experience. Apparently this was an issue with the version of cURL installed on my Digital Ocean box.
So the solution was to remove the version of cURL i had installed which was not installed correctly because i had built the binaries my self.
I installed the problematic cURL using these commands
wget -O curl.tar.gz http://curl.haxx.se/download/curl-7.42.0.tar.gz
tar -xvzf curl.tar.gz
cd curl-7.42.0
./configure
make
make install
I removed the problematic cURL that had https issues like this
which curl
(To tell me where the executable was located and it was located in usr/local/bin/curl)
Then i did
sudo rm -f /usr/local/bin/curl
(To remove the cURL giving issues)
Then i used the command
sudo yum install curl php5-curl
This installed cURL correctly for me. The i ran
curl --version
To confirm that https is now supported in the cURL version and it was.
I logged out of my droplet and logged back in. Then tried the
curl --version "https://sandbox.paypal.com/cgi-bin/webscr"
command and everything worked. I was able to connect to Paypal.
Thanks to everyone for their help and comments.
I think you need to enable fopen socket.You can ask hosting provider

Install Symfony on Windows behind proxy server with NTLM authentication

I tried to downlaod and install Symfony on a server at my company...
c:\> php -r "readfile('http://symfony.com/installer');" > symfony
..and got the following error (partly German, but you'll get the idea):
PHP Warning: readfile(http://symfony.com/installer): failed to open stream: Es konnte keine Verbindung hergestellt werd en, da der Zielcomputer die Verbindung verweigerte.
in Command line code on line 1
So I downloaded it manually over the browser (which worked fine) and tried to create a new site:
php symfony.phar new blog
Now I got this error:
[RuntimeException]
There was an error downloading Symfony from symfony.com server:
Client error response [url] http://symfony.com/download?v=Symfony_Standard_Vendors_latest.tgz [status code] 407 [re
ason phrase] Proxy Authentication Required
[GuzzleHttp\Exception\ClientException]
Client error response [url] http://symfony.com/download?v=Symfony_Standard_Vendors_latest.tgz [status code] 407 [re
ason phrase] Proxy Authentication Required
So I did a step back to see if I can do a cURL request in a PHP script. I used the following script to try it (my company is using a proxy server with NTLM authentication):
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.google.com');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXY, 'proxy.company.loc');
curl_setopt($ch, CURLOPT_PROXYPORT, 8080);
curl_setopt($ch, CURLOPT_PROXYTYPE, 'HTTP');
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:password');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
echo curl_exec($ch);
curl_close($ch);
And it worked fine.
What do I have to do to be able to install and use Symfony. Where do I define the proxy, the credentials and the NTLM method? I tried adding HTTP_PROXY in the env vars as "http://user:password#proxy.company.loc:8080", but that didn't help (maybe I also have to add the auth type NTLM somewhere).
The server is a Windows Server 2012 R2. PHP version is 5.6.5 and Apache is on 2.4.12.
Thanks for any help and sorry for any grammar errors!
I will describe solution which I use myself.
Download cntlm-0.92.3-setup.exe and install it (it will set up system service).
Configure cntlm.ini (C:\Program Files (x86)\Cntlm\cntlm.ini) - proxy address, no proxy, domain account etc.
Restart Cntlm Authentication Proxy service.
Set http_proxy/https_proxy to http://localhost:3128 (system wide method)
Try symfony installer now
Sometimes it could be a little bit slow but it works. I use this solution for all console apps that do not support integration with system wide proxy. Cntlm also works on unix based OS.
Hope that's help.

Categories