curl vs libcurl command using php-curl - php

I have a curl command that works perfectly from the command line that goes like so :
curl --cert /path/to/cert.pem \
--cert-type PEM \
--form "files[0]=#/path/to/file.csv" \
https://url.com/whatever
I can also run it successfully from php using
exec("curl --cert /path/to/cert.pem --cert-type PEM --form \"files[0]=#/path/to/file.csv\" https://url.com/whatever");
Translating the command to php-curl I got
$url = "https://url.com/whatever";
$certificate = "/path/to/cert.pem";
$filePath = "/path/to/file.csv";
$postData = array("files[0]" => "#".$filePath);
// Upload request
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSLCERT, $certificate);
curl_setopt($ch, CURLOPT_SSLCERTTYPE, "PEM");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
// I have tried WITH or WITHOUT the following options to no avail
// Note that SSL_VERIFYPEER false is not necessary -- I do not have a self-signed cert in the chain
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
$postUploadResponse = curl_exec($ch);
and this does not work. The message I get from the server is that the authentication has failed and that my certificate is not valid (though the exact same certificate works from the cmd line).
An important detail : that function runs perfectly well (with SSL_VERIFYPEER false as I use a self-signed cert locally) from my local XAMPP installation but the same code fails on the server.
The server is on Debian 8.3.
curl --version is
curl 7.38.0 (x86_64-pc-linux-gnu) libcurl/7.38.0 OpenSSL/1.0.1k zlib/1.2.8 libidn/1.29 libssh2/1.4.3 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API SPNEGO NTLM NTLM_WB SSL libz TLS-SRP
What could be causing this ? Is there anything that could be causing my certificate to not be sent properly when using libcurl ?

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.

cURL PUT Requests hangs

So here's my problem.
I'm using curl to access my CouchDB by HTTP. I recently updated my WAMP to the WAMP 3 64bit wich comes with PHP 5.6.16 and Apache 2.4.17. Therefore, since this upgrade, I discovered that I couldn't do PUT request anymore.
Env
PHP 5.6.16
Apache 2.4.17
Windows 10 64 bit
Wamp 3 64 bit
Curl --version
curl 7.49.1 (x86_64-pc-win32) libcurl/7.49.1 OpenSSL/1.0.2h nghttp2/1.11.1
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile NTLM SSL HTTP2
Code executed
So when I execute this :
<?php
$table="testname";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://localhost:5984/' . $table);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'validUser:validPass');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-type: application/json',
'Accept: */*'
));
$response = curl_exec($ch);
curl_close($ch);
echo $response;
I get a quick response from the server.
Then, I try to create a database :
<?php
$table = "testname";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://localhost:5984/' . $table);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'validUser:validPass');
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-type: application/json',
'Accept: */*'
));
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Problem
So, when I execute this code, the request will hang on curl_exec.
What's weird is that, after the timeout, the request will be received by CouchDB but no response will be given. It seems that my "Put" request are stacked in a buffer and they are waiting to be executed.
Verbose curl output
* Hostname in DNS cache was stale, zapped
* Trying ::1...
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5984 (#0)
* Server auth using Basic with user 'validUser'
> PUT /customers HTTP/1.1
Host: localhost:5984
Authorization: Basic dGVzdEFkbWluOnRlc3RQYXNzd29yZA==
Content-type: application/json
Accept: */*
* Operation timed out after 10000 milliseconds with 0 bytes received
* Closing connection 0
Hints
-I try to install a SSL certificate but It didn't seem to work. Having this certificate still installed can cause problems?
-I can do PUT request with a REST client on my Atom editor without problems.
-I seems like there is a problem in my network route internally. I'm saying this because It affected the PHP-Curl aswell as the Curl CLI. Also, I'm able to do GET request but the PUT request are like "hanging" for no reason and are "Accepted" by my CouchDB when the timeout occurs. It's like if I was sending long poll request.
What have been tested
Execute the same command on the command line -> Same result
Try a REST Client on my Atom editor with success
A friend of mine try to access to my database remotly with success (So CouchDB doesn't seem the problem)
Even if I tested with my Firewall disabled, uninstalling my antivirus ( Bitdefender Total Security 2016) fixed my issue.

curl error 411 when migrating from PHP 5.3 to 5.6

I'm migrating from PHP 5.3 to PHP 5.6.3.
When doing a curl request, it now gives me an error:
The requested URL returned error: 411 Length Required
All the data is the same. A vardump on the msg returns a string of 620. The length is correct, nothing of the variables are changed and contain the same data whether it is PHP 5.3 or PHP 5.6.3.
So in short; I have exact the same setup, data, format etc. but now curl gives a 411 error.
This is a snippet of my code:
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $this->_url);
curl_setopt($handle, CURLOPT_FAILONERROR, true);
curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: text/xml","SOAPAction: ".$request."","Content-length: ".strlen($msg)));
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, $msg);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($handle, CURLOPT_USERPWD, $this->_httpUser.':'.$this->_httpPassword);
$response = curl_exec($handle);
PHPINFO curl:
cURL support enabled
cURL Information 7.39.0
Age 3
Features
AsynchDNS Yes
CharConv No
Debug No
GSS-Negotiate No
IDN Yes
IPv6 Yes
krb4 No
Largefile Yes
libz Yes
NTLM Yes
NTLMWB No
SPNEGO Yes
SSL Yes
SSPI Yes
TLS-SRP No
Protocols dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp
Host i386-pc-win32
SSL Version OpenSSL/1.0.1i
ZLib Version 1.2.7.3
libSSH Version libssh2/1.4.3
Ok, I had to remove the content-length part since curl does this automatically for non 'put' requests.
The reason why my code worked under PHP 5.3 and not with PHP 5.6.3 is unknown to me. Yet this is the solution.

Get image with curl via https

I have script which gets image from http and it works fine, but when I try to get image from https link it is not working. I am using curl, and I have found this Get image via https and php but it is not working.
My code:
$image_url="https://ssl.gstatic.com/accounts/services/mail/phone.png";
$slika = getSslPage($image_url);
if(!empty($slika))
file_put_contents('vest.jpg', $slika);
function getSslPage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
phpinfo is giving me this information
Protocols: dict, file, ftp, gopher, http, imap, pop3, rtsp, smtp, telnet, tftp
and command line is showing https
root#server [~]# curl --version
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp
I have solved it by installing curl ssl
/scripts/easyapache
option 7 on the menu
select PHP
scroll down and select CURL with SSL
exit
save
Everything is working now

PHP Curl does not work on localhost?

I am using MAMP Pro 1.9.4 on Mac OSX
In phpinfo() I see curl is enabled
cURL support enabled
cURL Information 7.20.0
Age 3
Features
AsynchDNS No
Debug No
GSS-Negotiate No
IDN Yes
IPv6 Yes
Largefile Yes
NTLM Yes
SPNEGO No
SSL Yes
SSPI No
krb4 No
libz Yes
CharConv No
Protocols dict, file, ftp, ftps, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, smtp, smtps, telnet, tftp
Host i386-apple-darwin8.11.1
SSL Version OpenSSL/0.9.7l
ZLib Version 1.2.3
My script is to geocode lat long from Google apis.
It works online on my hosting providers server but not on localhost.. WHY??
$latlng = "44.3585230889,8.57745766643";
$lang = "it";
$geocodeURL = "http://maps.googleapis.com/maps/api/geocode/json?latlng=$latlng&sensor=false&language=$lang";
$ch = curl_init($geocodeURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
$geocode = json_decode($result);
$location = $geocode->results[0]->address_components[0]->long_name;
$city = $geocode->results[0]->address_components[1]->long_name;
$province = $geocode->results[0]->address_components[2]->long_name;
$region = $geocode->results[0]->address_components[3]->long_name;
$country = $geocode->results[0]->address_components[4]->long_name;
$geo_status = $geocode->status;
$geo_str = "$location, $city, $province, $region, $country";
} else {
$geo_status = "HTTP_FAIL_$httpCode";
$geo_str = "Failed: $geo_status";
}
It's not about proxy, it's about how to use googleapis.
Add CURLOPT_SSL_ on your code and set them into false
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
On a local server (eg XAMPP) with a self-signed certificate you must use:
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
Note: Despite being unsafe for testing environments it solves the problem.
Remember to activate for production servers !!!
It's probably a firewall issue. Curl by default tries to use port 1080, which is probably not open on your localhost / router / ISP.
You may need to set the SSL version and the matching Cipher for $ch:
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');
For the exact parameters you can pass to CURLOPT_SSLVERSION see:
http://php.net/manual/en/function.curl-setopt.php
Also the following can display errors related to SSL versions being used to help find exact version conflict you have:
$error = curl_error($ch);
echo $error;
More on this command: http://php.net/manual/en/ref.curl.php
If you are behind a proxy, you could try adding CURLOPT_PROXY, for example (assuming your proxy is on 192.168.1.2 port 3128):
$ch = curl_init($geocodeURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXY, "192.168.1.2:3128");
$result = curl_exec($ch);
Hope this helps.
In MAMP, if you are getting errors when connecting to HTTPS hosts, just set this option:
curl_setopt($ch, CURLOPT_SSLVERSION,3);
The equivalent by command line is:
curl -k -ssl3 https://www.your-secure-host.com
Do you actually have the curl binary installed? You can have the curl library installed with PHP without actually having the curl binary on your system. Drop to a shell prompt and type curl. (If it's standard on OSX then please forgive my ignorance - I'm not a Mac guy)
If your OS dont provide cacert.pem file to your local server for SSL certificate validation, you can download it and specify it in php.ini
cacert.pem
php.ini:
[openssl]
; The location of a Certificate Authority (CA) file on the local filesystem
; to use when verifying the identity of SSL/TLS peers. Most users should
; not specify a value for this directive as PHP will attempt to use the
; OS-managed cert stores in its absence. If specified, this value may still
; be overridden on a per-stream basis via the "cafile" SSL stream context
; option.
openssl.cafile=C:\wamp64\cacert.pem

Categories