Passing .PEM and .KEY as string in Curl using PHP
Solution 1
The answer is unfortunately as easy as it is simple: No, it is not possible.
The underlying libcurl actually has an API for providing keys and certs directly from memory, but the PHP/CURL extension only has support for providing them as files!
Bonus material:
If you're sure that your libcurl is built with OpenSSL, you can actually use the CURLOPT_SSL_CTX_FUNCTION option to do it. However:
-
that makes it an libcurl+OpenSSL specific solution
-
I don't think PHP/CURL exposes that function (enough) to allow this. You would probably need to extend the binding code first...
(I should add that I am the main author and maintainer of libcurl.)
Solution 2
Using tmpfile()
might suffice as a workaround.
$tempPemFile = tmpfile();
fwrite($tempPemFile, $pemfile);
$tempPemPath = stream_get_meta_data($tempPemFile);
$tempPemPath = $tempPemPath['uri'];
and then:
curl_setopt($ch, CURLOPT_SSLCERT, $tempPemPath);
but make sure you close it after so the tmp file is delete
fclose($tempPemFile);
Solution 3
You could create temporary files, write the strings into the files and then point to the temp files...
bianca
Updated on January 14, 2022Comments
-
bianca over 2 years
I've a CERT and private key files. I'm using cUrl and PHP to connect to another service. At the moment, I've cert and key in files and it works perfectly fine with following code:
$pemfile = "cert.pem"; $keyfile = "private_key.key"; $url = "someTestUrl"; $requestXml = "requestData"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); curl_setopt($ch, CURLOPT_FAILONERROR, 1); curl_setopt($ch, CURLOPT_SSLCERT, $pemfile); curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); curl_setopt($ch, CURLOPT_SSLKEY, $keyfile); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml')); curl_setopt($ch, CURLOPT_POSTFIELDS, $requestXml); $ret = curl_exec($ch);
My question is: Can I pass cert and key as strings rather passing them as files? I tried simply passing contents of respective files as strings like this:
$pemfile = "-----BEGIN CERTIFICATE-----CERTDATAASSTRING-----END CERTIFICATE-----"; $keyfile = "-----BEGIN RSA PRIVATE KEY-----PRIVATEKEYINCODE-----END RSA PRIVATE KEY-----";
...and needless to say...it didn't work :(
Any ideas? pointers? suggestions???
-
lisachenko almost 12 yearsThere are special filenames, supported by PHP and one of them is
php://memory
stream. Does libcurl support such filename? (not tested) -
Daniel Stenberg almost 12 yearsI don't know. If they work as regular files to libcurl then they will work, but I doubt they do so my guess would be that they don't work...
-
netcoder almost 12 years@Alexander: For options with string values (e.g.: CURLOPT_URL, CURLOPT_SSLCERT, etc.),
php-curl
simply converts the passed value to a C-string and pass it directly tolibcurl
. Sincelibcurl
knows nothing aboutphp://memory
, it's not possible. -
lisachenko almost 12 years@netcoder I found workaround for this in the bug report: bugs.php.net/bug.php?id=43468. CURLOPT_READFUNCTION can be used to add a support for such stream to the CURL. Need to check that...
-
Daniel Stenberg almost 12 years@Alexander: no, that's not true. You cannot pass a key to libcurl with the user of the read callback.
-
Josh Bradley almost 7 years@DanielStenberg It's been several years since you addressed this question. Can you provide an update on this? Does libcurl now have the API to pass in cert and key files as a string? Some situations ultimately require the keys to be saved in a file unencrypted (not good!) before using curl.