27

I am facing an SSL issue with the curlcommand. I want to reach an URL using my SSL client certificate and private key.

This is my command:

$ curl -k -v "https://myurl.com/" --cert ./certificate.pem --key ./private.key

* About to connect() to xx.xx.xx.xx port 23444 (#0)
*   Trying xx.xx.xx.xx... connected
* Connected to xx.xx.xx.xx (xx.xx.xx.xx) port 23444 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* warning: ignoring value of ssl.verifyhost
* Unable to load client key -8178.
* NSS error -8178
* Closing connection #0
curl: (58) Unable to load client key -8178.

The key is password protected, curl is not asking me to enter the password, which is very strange. Even if I pass the password with --pass, I still get the same error.

It seems that the argument --key is not considered, because If I replaced with foo.key, which doesn't exist on my filesystem, I still get the same error.

However, If use:

$ wget --certificate=./certificate.pem --private-key=private.key "https://myurl.com/" --no-check-certificate

I am able to reach my URL.

Do you have any idea?

slm
  • 15,396
  • 12
  • 109
  • 124
hzrari
  • 1,803
  • 1
  • 15
  • 26
  • Permission issue on what? – hzrari Jan 07 '14 at 13:13
  • a workaround is to import your certificate in NSS database, like here: http://stackoverflow.com/questions/15773806/nss-client-certificate-not-found-nickname-not-specified I searched for another solution before you, but haven't found it. If you do, please post it – thibon Feb 18 '14 at 17:18

2 Answers2

31

I've gone through the same problem, and found a solution finally, maybe it can help you.

The failure was due to the private key in PKCS#8 format:

  • a PKCS#8 private key starts with -----BEGIN ENCRYPTED PRIVATE KEY----- header
    or
    -----BEGIN PRIVATE KEY----- header

    With this key curl + openssl will works, but curl + nss + libnsspem.so wouldn't.

  • with a RSA private key which starts with
    -----BEGIN RSA PRIVATE KEY----- header

    both curl + openssl and curl + nss + libnsspem.so will work.

So use this command

openssl pkcs8 -in path/to/your/pkcs8/key -out path/to/rsa/key

to convert the PKCS#8 key to traditional RSA key.

Community
  • 1
  • 1
jfly
  • 7,715
  • 3
  • 35
  • 65
  • Thank you for your answer. It may work in theory, I can't use this because in my use case I am not allowed to generate a new key for each key in my database, even temporary etc... Finally I had to use wget instead... I just posted it to know the answer and to share it with people facing the same issue ;-) – hzrari Mar 20 '14 at 10:13
  • 1
    For completeness, the correct parameters for curl are then: `--cert ./certificate.pem --key ./newkey.pem` where _newkey.pem_ is the new RSA copy of the key created wuth openssl. – David Balažic Apr 16 '15 at 15:59
  • 1
    I have the same issue, but I dont WANT to store an unencrypted key file. Isn't there a way that CURL can prompt me for the password and use the encrypted key? – Brad Apr 13 '17 at 14:58
  • 4
    @Brad Just add a passphrase to the RSA private key: `openssl rsa -des3 -in your.key -out your.encrypted.key`. `-des3` means encryption algorithm, you can use others, such as aes128, aes192. – jfly Apr 13 '17 at 15:49
  • @jfly I did - and It always give me the -8178 error reading the key - never prompts my for the password. I verified PEM formats, and tried a few different algoritms. ONLY works for unencrypted key. – Brad Apr 13 '17 at 18:27
  • @jfly I just had same problem and `openssl rsa -des3 -in your.key -out your.encrypted.key` worked for me - now curl works again and key is still encrypted. – cronfy Aug 03 '17 at 15:14
  • @jfly I tried your advice and apparently the nss variant of curl on Centos accepts only keys that are unencrypted or encrypted via -des3. No other ciphers are accepted (Centos 7.4). – Ján Lalinský Mar 20 '18 at 15:27
  • 1
    Apparently this is a known bug, reported in 2016. nss-pem does not support keys that use encryption other than des. -- https://bugzilla.redhat.com/show_bug.cgi?id=1369251 – Ján Lalinský Mar 20 '18 at 18:07
4

If your certificate has a passphrase you should add it after the certificate name:

curl -k -v "https://myurl.com/" --cert ./certificate.pem:passphrase --key ./private.key
Baryo
  • 314
  • 1
  • 9