could not load PEM client certificate, OpenSSL - php

I have four files provided from client side.
test.jks
test.pem
key.pub
test.p12
I have to send json array on this url using curl. so i'm confused what is the use of other files ? like .p12 , .jks. what is the key from above files ?
I started with .pem file included using this link :
How to send a curl request with pem certificate via PHP?
So , I got following errors.
Error :
Curl Error: could not load PEM client certificate, OpenSSL error
error:0906D06C:PEM routines:PEM_read_bio:no start line, (no key found,
wrong pass phrase, or wrong file format?)No HTTP code was returned
Code :
$url = "https://adfapi.adftest.rightmove.com/v1/property/sendpropertydetails";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$pemFile = tmpfile();
fwrite($pemFile, "test.pem");//the path for the pem file
$tempPemPath = stream_get_meta_data($pemFile);
$tempPemPath = $tempPemPath['uri'];
curl_setopt($ch, CURLOPT_SSLCERT, $tempPemPath);
//curl_setopt($ch, CURLOPT_SSLCERT, "test.pem" );
curl_setopt($ch,CURLOPT_SSLCERTTYPE,"PEM");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, True);
curl_setopt($ch, CURLOPT_POST, True);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$result = curl_exec($ch);
if(!$result)
{
echo "Curl Error: " . curl_error($ch);
}
else
{
echo "Success: ". $result;
}
$info = curl_getinfo($ch);
curl_close($ch); // close cURL handler
if (empty($info['http_code'])) {
die("No HTTP code was returned");
} else {
// load the HTTP codes
$http_codes = parse_ini_file("path/to/the/ini/file/I/pasted/above");
// echo results
echo "The server responded: <br />";
echo $info['http_code'] . " " . $http_codes[$info['http_code']];
}

Since you are using the filename - Try an absolute path.
e.g
curl_setopt($ch, CURLOPT_SSLCERT, 'c:/wamp64/www/bit-tool/www/testcert.pem');

Related

Curl Request working but not inside laravel

Hi everyone i have crul request when i use it in single php page without laravel it work fine but if i put it inside laraevl controller to use it not working and return code status 0
My Request
$data = '{"PaymentInquiryV4RequestMessage":{"RefNum":"123456"}}';
$ch = curl_init('https://b2btest.stcpay.com.sa/B2B.DirectPayment.WebApi/DirectPayment/V4/PaymentInquiry');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,1);
curl_setopt($ch, CURLOPT_SSLCERT, 'crt.crt');
curl_setopt($ch, CURLOPT_SSLKEY, 'key.key');
curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'X-ClientCode: XXXXXXXXXXX'
)
);
$result = curl_exec($ch);
$result = json_decode($result, true);
print_r ($result);
when dealing with curl always start by debugging errors, which you can enable like
$result = curl_exec($ch);
if (curl_errno($ch)) {
$error_msg = curl_error($ch);
echo $error_msg;
}
and as you mentioned in comment, you received below error after adding above code:
could not load PEM client certificate, OpenSSL error error:02001002:system library:fopen:No such file or directory, (no key found, wrong pass phrase, or wrong file format?)
It clearly indicate it can't find your certificate files, update path to those files in your call , like if your certificates are in directory /var/www/certificate/, your code would be
curl_setopt($ch, CURLOPT_SSLCERT, '/var/www/certificate/crt.crt');
curl_setopt($ch, CURLOPT_SSLKEY, '/var/www/certificate/key.key');
and make sure cert files are readable by setting proper permissions.
p.s you can also use Laravel helpers to get the path
base_path(); // '/var/www/mysite'
app_path(); // '/var/www/mysite/app'
storage_path(); // '/var/www/mysite/storage'
so you call will contain like
curl_setopt($ch, CURLOPT_SSLCERT, base_path().'/certificate/crt.crt');
curl_setopt($ch, CURLOPT_SSLKEY, base_path().'/certificate/key.key');

Upload image with curl put request from url

I was trying to upload image using curl put request, And was able to upload image if the image is stored in local directory. but the problem is that i have to upload image from another image url.
could anyone help me.
$localfile = "testing.jpg";
// echo filesize($localfile); die;
$url = API_URL . "pages/343/files/=".$localfile."?description=testing";
$fp = fopen ($localfile, "r");
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_USERPWD, API_USERNAME . ":" . API_PASSWORD);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
$http_result = curl_exec($ch);
$error = curl_error($ch);
$http_code = curl_getinfo($ch ,CURLINFO_HTTP_CODE);
// $jsonOutput = json_decode($http_result, true);
curl_close($ch);
fclose($fp);
i have tried to change $localfile to
$localfile = "https://someurl/someimage.png";
but it gave me following error.
Warning: curl_setopt(): cannot represent a stream of type tcp_socket/ssl as a STDIO FILE* in C:\xampp\htdocs\newPutMedia.php on line 29
Warning: filesize(): stat failed for https://help.optimizely.com/hc/en-us/article_attachments/200205465/1._Site-Wide_Addition_gmc_BEFORE.png in C:\xampp\htdocs\newPutMedia.php on line 30
Apparently this is a bug in PHP cURL. You can use the bug fix as mentioned here or you can do this :
Copy the file from URL to your local directory :
file_put_contents(__DIR_\_ . "/testing.jpg", file_get_contents($url));
Use the new file stored in your server for cURL PUT request :
$localfile = __DIR_\_ . "/testing.jpg";
Since the bug does not exist for file reading from your server, the bug won't cause errors and this would perfectly work.

How to send a curl request with pem certificate via PHP?

I have a php script in my Apache server that have to send a curl request to a partner's server.
Partner give me a .pem file that I have to attach to every call I do to its api.
My php script is the follow:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSLCERT, "test.pem" );
curl_setopt($ch,CURLOPT_SSLCERTTYPE,"PEM");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, True);
curl_setopt($ch, CURLOPT_POST, True);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$result = curl_exec($ch);
if(!$result)
{
echo "Curl Error: " . curl_error($ch);
}
else
{
echo "Success: ". $result;
}
curl_close($ch);
It returns:
Curl Error: unable to set private key file: 'test.pem' type PEM
Consider that it sends me .pem file and says "it has no passphrase"
I think that you need to use the tmpfile() and stream_get_meta_data.
$pemFile = tmpfile();
fwrite($pemFile, "test.pem");//the path for the pem file
$tempPemPath = stream_get_meta_data($pemFile);
$tempPemPath = $tempPemPath['uri'];
curl_setopt($ch, CURLOPT_SSLCERT, $tempPemPath);
Source: This answer here in SO helps me with similar problem.
I think you're missing
curl_setopt($ch, CURLOPT_CAINFO, 'test.pem');
Have a look at cURL is unable to use client certificate , in local server
for more about using client certificates in curl via PHP

how to access xml file of ssl or https type domain and store in our server using php

I want to access an XML file stored on another domain. The domain has an SSL certificate. I want to store it in my server folder. How can I achieve this in PHP? I am able to download without HTTPS from other sites, but unable to do it with HTTPS.
<?PHP
$dom = new DOMDocument();
$dom->load('www.123.com/abc.xml');
$dom->save('filename.xml');
?>
We are going to use Curl to download this file. There are 2 option.
The quick fix
The proper fix
The quick fix, first.
Warning: this can introduce security issues that SSL is designed to protect against.
set:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); to false
<?PHP
$url = "https://data.gov.in/sites/default/files/Date-Wise-Prices-all-Commodity.xml";
// create curl resource
$ch = curl_init();
//Now set some options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Download the given URL, and return output
$xml = curl_exec($ch);
// Check for errors
if (curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch);
}
// Close the cURL resource, and free system resources
curl_close($ch);
// Write the string $xml to a file, data.xml
if (file_put_contents ('data.xml', $xml) !== false) {
echo 'Success!';
} else {
echo 'Failed';
}
?>
The second, and proper fix. Set 3 options:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . '\CAcert.crt');
The last thing you need to do is download the CA certificate.
Go to, - http://curl.haxx.se/docs/caextract.html -> click 'cacert.pem' -> copie/paste the text in to a text editor -> save the file as 'CAcert.pem' Check it isn't 'CAcert.pem.txt'
<?PHP
$url = "https://data.gov.in/sites/default/files/Date-Wise-Prices-all-Commodity.xml";
// create curl resource
$ch = curl_init();
//Now set some options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . '\CAcert.crt');
// Download the given URL, and return output
$xml = curl_exec($ch);
// Check for errors
if (curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch);
}
// Close the cURL resource, and free system resources
curl_close($ch);
// Write the string $xml to a file, data.xml
if (file_put_contents ('data.xml', $xml) !== false) {
echo 'Success!';
} else {
echo 'Failed';
}
?>

Failing to upload file with curl in heroku php app

I'm getting the response "failed creating formpost data" from curl whenever I try to upload a file. I'm sensing from other posts on the web that it's the filepath that's wrong, but I can't seem to get an absolute path on heroku.
When i do dirname(__FILE__) all I get is /app/www/ that can't be right can it? How do I get the absolute file path in a heroku app?
this is my entire line for the image path to be included in post data
"#".dirname(__FILE__).'/images/wallimages/'.random_pic()
and my curl setup:
$ch = curl_init('https://url.com/'.$url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $attachment);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
if(curl_errno($ch))
{
return 'Curl error: ' . curl_error($ch);
}
curl_close ($ch);
return $result;
I suspect the root cause of your problem may be this line from the manual:
As of PHP 5.2.0, value must be an array if files are passed to this option with the # prefix.
In any case, try this code and if it doesn't work, let me know what error message(s) you get so I can debug:
$uploadPath = rtrim(dirname(__FILE__),'/').'/images/wallimages/'.random_pic();
if (!is_file($uploadPath)) die("The file '$uploadPath' does not exist");
if (!is_readable($uploadPath)) die("The file '$uploadPath' is not readable");
$postFields = array (
'nameOfFileControl' => "#$uploadPath",
'someOtherFormControl' => 'some value'
// Adjust this array to match your post fields.
// Ensure you keep the array in this format!
);
$ch = curl_init('https://url.com/'.$url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$result = curl_exec($ch);
if(curl_errno($ch))
{
return 'Curl error: ' . curl_error($ch);
}
curl_close ($ch);
return $result;

Categories