1

I am trying to use free client certificate by cacert.org in curl call. check following...

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://url.com');
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSLCERT, 'cert.crt');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

I have downloaded certificate as PEM, now i am getting following error...

unable to set private key file: 'cert.crt' type PEM

I have tried all way but could not fix, tried google as well. Please help.

seoppc
  • 2,766
  • 7
  • 44
  • 76
  • When you exported the certificate did it include the private key? – drew010 Dec 08 '15 at 22:55
  • @drew010 No, even i have bought a paid ssl from comodo but that didn't solve my problem too. – seoppc Dec 08 '15 at 23:21
  • What are you trying to do? `CURLOPT_SSLCERT` is for specifying a client authentication certificate which is used for authenticating with a remote server. Some CA's use them instead of passwords for logging in to manage your account, but client certs aren't super common. Are you looking for `CURLOPT_CAINFO` instead? – drew010 Dec 08 '15 at 23:25
  • @drew010 I have tried both but nothing worked, the website wants me to use client certificate while making request. – seoppc Dec 09 '15 at 00:24
  • Okay was just confirming. The issue is that cURL doesn't seem to have the private key for the client certificate which gives the error "unable to set private key file". Your crt file appears to be PEM format so it should just be base64 encoded. Does it contain a line `-----BEGIN ENCRYPTED PRIVATE KEY-----` or `-----BEGIN RSA PRIVATE KEY-----` or do you only see `-----BEGIN CERTIFICATE-----`? – drew010 Dec 09 '15 at 00:27
  • @drew010 No, it starts with `-----BEGIN CERTIFICATE-----` , i think you are understanding my problem now. :) – seoppc Dec 09 '15 at 19:39

1 Answers1

0

I believe the problem is that your certificate file does not contain the private key and it isn't being supplied separately using the CURLOPT_SSLKEY option which points to the corresponding private key for the certificate.

I'm guessing the certificate was issued to you from the CA and installed in your browser. When this happens the private key is stored by the browser in a secure location separate from the cert (depends on the OS & browser).

Most browsers won't let you export the certificate and private key without encrypting it (supplying a password). But based on the contents of your PEM file, there is no corresponding private key.

To resolve this you'll probably have to go through a few steps:

  • Export the cert from the browser again and make sure it includes the private key
  • Chrome on Win/Linux and Internet Explorer on Windows will require you to enter a password. The certificate should be exported as a PKCS#12 (.p12) file

The problem now is that the private key is encrypted and it needs to be unencrypted for cURL as far as I know

  • Use openssl to decrypt the private key and export the certificate and key to PEM format
  • openssl pkcs12 -in cert.p12 -nodes (this will ask for the password used to encrypt when you exported from the browser) (cert.p12 is the cert & private key in PKCS12 format. -nodes allows the private key to be exported without encryption)

This will print to standard output the certificate and key in PEM format.

You should see two sections:

-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

and

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

You already have the cert most likely, but you need to save the private key to another file. Since it isn't encrypted on the server, take great care to set the permissions properly, typically 0400 so other users can't access it

drew010
  • 68,777
  • 11
  • 134
  • 162