12

Excuse me if the question is silly, but I'm a novice in this area. I need to connect to a service via SSL from a Drupal 7 site. I have a file with a ".p12" extension and a password for it. Also, I use PHP 7.1 1 and Windows 7 64x. I converted .p12-file into .pem-file using the following command.

openssl pkcs12 -in myfile.p12 -out myfile.pem 

Before I installed Openssl into my computer and added paths into Windows. After it I'm trying to use the following code for connecting to the server using CURL functions.

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'my_addr');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSLCERT, 'myfile.pem');
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, 'mypsw');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$result = curl_exec($ch);

if ($result === FALSE){
  $curl_error = curl_error($ch);
}
curl_close($ch);

Unfortunately, curl_exec returns FALSE and curl_error returns the following:

could not load PEM client certificate, OpenSSL error error:02001003:system library:fopen:No such process, (no key found, wrong pass phrase, or wrong file format?)

I decide to execute this code on the client's site which is on a Linux shared hosting, whereas my localhost works on Windows 7 64x. The code is executed without any errors, but curl_exec returns a void string.

I want to clarify, what am I doing wrong and why PEM client certificate doesn't want to load? What should I do on my localhost to solve this problem? I can't give up using Windows 7 and start using Linux instead it.

Yakimkin Roman
  • 277
  • 1
  • 2
  • 11
  • 1
    Have you tried looking at the .pem file. My guess is that the file contains the certificate and the key. https://stackoverflow.com/a/15144560/254234 This is an invalid format to load afterwards in CURLOPT_SSLCERT. The difference between Windows/Linux might be that on your hosting provider the error log and error level/diplay errors is different. – DrDol Oct 13 '18 at 19:34
  • I tried using different ways, but the same error is displayed. – Yakimkin Roman Oct 14 '18 at 08:54
  • Have you tried to define the path to .pem in a absolute way? Without the content of the .pem file it's not easy do debug this issue. But by reveal the .pem key you might expose your key. – DrDol Oct 15 '18 at 14:24
  • You can also check the client certificate with `openssl x509 -in myfile.pem -noout -text` – DrDol Oct 15 '18 at 14:28
  • You can verify which path used by your php curl to get pem file , maybe it's just a configuration mystake – Fky Mar 12 '19 at 14:21
  • Since you only use the filename - have you verified that the file is found? Try an absolute path... – Honk der Hase Mar 13 '19 at 18:42
  • What version of cURL are you using? Because CURLOPT_SSLCERTPASSWD is no longer a valid keyword after 7.9.2... see here: https://curl.haxx.se/libcurl/c/CURLOPT_KEYPASSWD.html – parttimeturtle Mar 13 '19 at 22:35
  • 1
    Do you have `OPENSSL_CONF` env variable set? If so, does it point to correct config file? – Styx Mar 15 '19 at 20:18
  • change curl_exec() to ```$stderr=tmpfile(); curl_setopt_array($ch,array(CURLOPT_VERBOSE=>1,CURLOPT_STDERR=>$stderr)); $result = curl_exec($ch); /* https://bugs.php.net/bug.php?id=76268 */ rewind($stderr); var_dump(stream_get_contents($stderr)); fclose($stderr);``` - what do you get? – hanshenrik Mar 16 '19 at 10:30
  • according to example you should provide `CURLOPT_SSLCERT`, `CURLOPT_SSLKEY` and `CURLOPT_KEYPASSWD` Also: use absolute paths. – bato3 Mar 18 '19 at 08:10
  • Have you solved this problem? I have this problem also. I tried with CURL, Guzzle and SoapClient but I couldnt solve it yet. – ali Falahati Jun 15 '21 at 08:06

2 Answers2

3

For a SSL verification you need a cert in pem format, it's associated private key (in openssl format) and the root certificate of the certification authoritity that signed your certificate in pem format.

Check this full sample :

PHP:path of CURLOPT_SSLCERT

The error message is not really clear if your are not informed but it say it :

could not load PEM client certificate, OpenSSL error error:02001003:system library:fopen:No such process, (no key found, wrong pass phrase, or wrong file format?)

Regards,

2

i bet the error will be easier to understand if you change it to

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'my_addr');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
$pem=realpath("myfile.pem");
if(!$pem || !is_readable($pem)){
    die("error: myfile.pem is not readable! realpath: \"{$pem}\" - working dir: \"".getcwd()."\" effective user: ".print_r(posix_getpwuid(posix_geteuid()),true));
}
curl_setopt($ch, CURLOPT_SSLCERT, $pem);

.. most likely the pem file is not readable by the account that php is running under (eg if you created the file as root and the owner is root:root and the permissions is a-r and php is running under the account www-data), another explanation is that the file plain out doesn't exist - yet another explanation is that you run chdir() prior to running curl_exec(), and since you're using a relative filepath, the relative path is no longer valid when running curl_exec() (but using realpath(), as i did above, solves this last issue)

hanshenrik
  • 19,904
  • 4
  • 43
  • 89