I'm trying to get a simple PHP cURL request to a REST API to work, but I'm getting this error no matter what I try:
error:14077410:SSL routines:func(119):reason(1040)
My PHP code is:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://jsonplaceholder.typicode.com/users");
curl_setopt($ch, CURLOPT_FAILONERROR, true);
$response = curl_exec($ch);
echo $response;
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
echo $error_msg;
}
curl_close($ch);
This works just fine on other servers, such as here on tehplayground.com
Here is some info from phpinfo() on my server:
PHP Version 5.3.6
cURL support enabled
cURL Information 7.12.1
Age 2
Features
AsynchDNS No
Debug No
GSS-Negotiate Yes
IDN Yes
IPv6 Yes
Largefile Yes
NTLM Yes
SPNEGO No
SSL Yes
krb4 No
libz Yes
Protocols ftp, gopher, telnet, dict, ldap, http, file, https, ftps
Host i386-redhat-linux-gnu
SSL Version OpenSSL/0.9.7a
ZLib Version 1.2.1.2
Any idea what's wrong? (I cannot change the server I'm using.)
Related
I can't force curl to use tls 1.2. Whatever i tried its only uses tls 1.3.
There is my source code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.howsmyssl.com/a/check");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
//also tried *6* => same response.
//also tried *5* => same response.
//also tried *4* => same response.
//also tried *3* => same response.
//also tried *2* => same response.
//also tried *1* => same response.
//also tried *0* => same response.
//also tried *CURL_SSLVERSION_MAX_TLSv1_2* => Undefined constant "CURL_SSLVERSION_MAX_TLSv1_2" error.
$response = curl_exec($ch);
curl_close($ch);
$tlsVer = json_decode($response, true);
echo "<h1>Your TSL version is: <u>" . ($tlsVer['tls_version'] ?: 'no TLS support') . "</u></h1>";
Response is always:
<h1>Your TSL version is: <u>TLS 1.3</u></h1>
Versions from phpinfo() is below:
Curl version: 7.87.0
Open ssl version: OpenSSL 1.0.2k-fips 26 Jan 2017
php version: 8.2.2
Edit: My server previously had curl 7.29.0, I updated to 7.87.0.
Edit2: More details from phpinfo();
openssl
OpenSSL support: enabled
OpenSSL Library Version: OpenSSL 1.0.2k-fips 26 Jan 2017
OpenSSL Header Version: OpenSSL 1.0.2k 26 Jan 2017
Openssl default config: /etc/pki/tls/openssl.cnf
curl
cURL support enabled
cURL Information 7.87.0
Age 10
Features
AsynchDNS: Yes
CharConv: No
Debug: No
GSS-Negotiate: No
IDN: No
IPv6: Yes
krb4: No
Largefile: Yes
libz: Yes
NTLM: Yes
NTLMWB: Yes
SPNEGO: Yes
SSL: Yes
SSPI:No
TLS-SRP: No
Protocols: dict, file, ftp, ftps, gopher, gophers, http, https, imap, imaps, ldap, ldaps, mqtt, pop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp
Host: x86_64-redhat-linux-gnu
SSL Version: NSS/3.79
ZLib Version 1.2.7
libSSH Version: libssh2/1.10.0
The documentation on the CURL website is somewhat clear:
CURLOPT_SSLVERSION - preferred TLS/SSL version
[...]
CURL_SSLVERSION_TLSv1_2
TLS v1.2 or later (Added in 7.34.0)
Note that it says or later but you want to enforce a maximum:
The maximum TLS version can be set by using one of the
CURL_SSLVERSION_MAX_ macros below.
CURL_SSLVERSION_MAX_TLSv1_2
The flag defines maximum supported TLS version as TLS v1.2. (Added in
7.54.0)
The constants should be available in your combination of PHP + curl. If not, you can look them up here. CURL_SSLVERSION_MAX_TLSv1_2 would be 0b110_00000000_00000000.
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.
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 ?
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.
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