send multiple .crt certificate with curl in php - php

I want to send two .crt certificates with curl in php.
I am using this code.
$firstcalldata = "csv file data";
$target_url = www.example.com;
$ch = curl_init($target_url);
curl_setopt($ch, CURLOPT_VERBOSE, '1');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CAINFO,"C:/Users/admin/Desktop/CERT/PSCERT.pem");
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "C:/Users/admin/Desktop/CERT/PSCERT-C.crt");
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, $firstcalldata);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/csv'));
$result = curl_exec($ch);
echo $result;
curl_close($ch);`
I am sending also a csv file to $target_url.
But all time I am getting 403 - Forbidden: Access is denied.

You're not really saying what you want to accomplish, you're just asking a very weird question with no answer. You example doesn't send the .crt at all, it uses it to verify the server's certificate. And CAINFO is meant to point to a file holding a full bundle (like one of those you can get at curl's caextract page)
But you disable both VERIFYPEER and VERIFYHOST so you don't actually need any CA cert!?
What exactly do you want to do? Note also how getting a 403 back means that you already communicate fine over the TLS layer.

Related

PHP Curl - SSL peer had some unspecified issue with the certificate it received

This is the request I'm sending with my PHP code-
$url = 'https://mywebserviceurl.com';
$method='GET';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_VERBOSE, '1');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, '2');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 'TRUE');
curl_setopt($ch, CURLOPT_CAINFO, __DIR__.'/print_ca_ca.cer');
curl_setopt($ch, CURLOPT_SSLCERT, __DIR__.'/print_ca_cert.cer');
curl_setopt($ch, CURLOPT_SSLKEY, __DIR__.'/print_ca_key_decr.pem');
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, 'somepassword');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$resp = json_encode($response);
$this->setErrorCodeMessage('401', 'Response-> '.$resp); //get a False here
$error = curl_error($ch);
$this->setErrorCodeMessage('401', 'Error-> '.$error); //get Error here
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status_code == '200' && !empty($response)) {
$this->setErrorCodeMessage('401', 'Inside 200 OK..');
}
The Error that I see on my Error Logs is-
SSL peer had some unspecified issue with the certificate it received.
When I do php -a and try to run the request as is on the shell, along with the above error line I also get the following-
NSS error -12224 (SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT)
I originally had a p12 file and got a ca chain(.cer file), ssl cert(.cer file) and key files(.pem file) from it using the openssl commands, and I'm using these files with the Curl request.
At this point I've tried everything; using pem,crt,cer files, setting CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER to different values and also tried a POST request, but i keep getting SSL peer had some unspecified issue with the certificate it received.
Is there something that I'm doing wrong? Any suggestions?
PS- I've used the original P12 file and its password on Postman and have been able to send both GET/POST requests without issues.
The error you receive is due to the server not accepting your client certificate (the print_ca_cert.cer). CURLOPT_SSL_VERIFYHOST etc will not help since these option are about verifying the server certificate by the client.
It is unclear what the server does not like with your client certificate since it is unknown what the requirements are for this certificate and what's actually in the files you've received. It might be that the print_ca_ca.cer is not the CA for the server certificate which you configure with CURLOPT_CAINFO but that it is an intermediate CA you need to send together with your client certificate. In this case you need to append your print_ca_ca.cer to your print_ca_cert.cer. But again, these are just speculations since nothing is known about the contents of these files.

php curl is not working over https

I am trying to fetch data from rest api(https) using curl. I have downloaded cacert.pem from http://curl.haxx.se/docs/caextract.html and moved into project root directory. Here is my code but it's not working. Can anyone help me?
$curl = curl_init();
// Set some options
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
curl_setopt($curl, CURLOPT_CAINFO, __DIR__.DIRECTORY_SEPARATOR.'cacert.pem');
curl_setopt($curl, CURLOPT_URL, 'https://startupgenome.com/api/2/boulder-co');
// Send the request & save response to $resp
$resp = curl_exec($curl);
curl_close($curl);
print_r($resp);
There are some problems. If you open your API url https://startupgenome.co/api/2/boulder-co you can see that the certificate is not valid. If you accept them you get an 404 (Well this doesn't seem right.).
So i think you should first insert the correct URL.
The second is. If the certificate is not valid on the server side you can't verify the host and your cacert.pem make no sense if the destination has no valid certificate.
If you really want to access that page then disable the checks but don't forget to enable that on production mode.
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);

PHP connect to HTTPS site through proxy

I've got the following problem: there is an HTTPS web site, and I need to connect to it through a proxy. Here are my cURL setopts:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROXY, '100.100.100.100:8080');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $ua);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_error($ch);
outputs Failed connect to ######.com:8080; No error
Where 100.100.100.100:8080 is a placeholder for a valid HTTPS proxy. This doesn't work. How do I make cURL connect to an HTTPS website through a proxy? I would really like a soultion that would work through not only HTTPS proxies. Also, I would best prefer a method using cURL, but if there is a better way to do it, without cURL, I could use it instead.
Update:
Add
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
It will prevent your HTTP proxy to parse your request headers and to act more transparently - like a tunnel.
initial answer, not interesting
Your code looks OK, and I assume you checked the trivial issues, so the problem is probably that the SSL certificate verification fails. It's the case if the certificate is self signed by example.
Try
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
to allow a request that allows using a self signed certificate.

cURL request using socks5 proxy fails when using PHP, but it works through the command line

cURL + proxy noob here, having a hard time. I'm having trouble trying to retrieve a web page from a remote secure server via a proxy. Everything has apparently been set up correctly by a remote dev, such that the following command line instruction works and returns what we're looking for:
curl -k --socks5-hostname localhost:xxxx https://hostname/
However, the following PHP does not echo the requested webpage. Instead it echoes the error 'Couldn't resolve host name':
$proxy = 'localhost:xxxx';
$url = 'https://hostname/';
//$proxyauth = 'user:password';
$ch = curl_init();
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
//curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyauth);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_URL, $url);
$curl_scraped_page = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error)
echo $error;
elseif ($curl_scraped_page)
echo $curl_scraped_page;
If the $url is changed to a public page, such as Google, the request is successful and everyone is happy.
The connection requires an SSH tunnel if that changes anything at all. The tunnel is open and functioning, as proven by the command line request succeeding.
Is there something obvious that is being missed here?
You need to set option CURLOPT_PROXYTYPE to CURLPROXY_SOCKS5_HOSTNAME, which sadly wasn't defined in old PHP versions, circa pre-5.6; if you have earlier in but you can explicitly use its value, which is equal to 7:
curl_setopt($ch, CURLOPT_PROXYTYPE, 7);
In the option CURLOPT_PROXYTYPE you need to set CURLPROXY_SOCKS5_HOSTNAME option instead of CURLPROXY_SOCKS5.
In this case, the DNS query (for hostname resolving) will be sent to SOCKS proxy and not resolved in the local network.
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME);
This constant available since PHP 5.5.23 and PHP 5.6.7 and cURL 7.18.0, so you can simply use it.

How to set hostname using php curl for a specific ip

Hi I have a server which has several virtual hosts set up on it.
I wanted to make a curl request to this server's ip using php.
Also I wanted to make this request to a specific hostname on the server's ip.
Is there a way to do it?
A bit more elaboration :
I want to make a curl requests between my servers using internal LAN, using their internal IP. The issue is that I have several sites hosted on this server. So when i make a curl request to the internal IP of the server.. something like (curl_init(xxx.xxx.xxx.xxx)), I want to be able to be tell apache to go to a particular folder pointed to by a virtual host. I hope that made the question a bit more clear.. – Vishesh Joshi 3 mins ago edit
You can set the host header in the curl request:
<?php
$ch = curl_init('XXX.XXX.XXX.XXX');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: subdomain.hostname.com'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);
For HTTPS sites use CURLOPT_RESOLVE which exists in every PHP version since PHP 5.5.
<?php
$ch = curl_init('https://www.example.com/');
// note: array used here
curl_setopt($ch, CURLOPT_RESOLVE, array(
"www.example.com:443:172.16.1.1",
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$result = curl_exec($ch);
Sample output:
* Added www.example.com:443:172.16.1.1 to DNS cache
* Hostname www.example.com was found in DNS cache
* Trying 172.16.1.1...
Base on Leigh Simpson,
It works, but I need query string attach with it.
That's what I work around:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://xxx.xxx.xxx.xxx/index.php?page=api&action=getdifficulty");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: subdomain.hostname.com'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);
?>

Categories