Passing .PEM and .KEY as string in Curl using PHP

22,865

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:

  1. that makes it an libcurl+OpenSSL specific solution

  2. 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...

Share:
22,865
bianca
Author by

bianca

Updated on January 14, 2022

Comments

  • bianca
    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
    lisachenko almost 12 years
    There are special filenames, supported by PHP and one of them is php://memory stream. Does libcurl support such filename? (not tested)
  • Daniel Stenberg
    Daniel Stenberg almost 12 years
    I 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
    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 to libcurl. Since libcurl knows nothing about php://memory, it's not possible.
  • lisachenko
    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
    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
    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.