curl command - Unable to load client cert -8018

I already fixed this problem, so I will post the solution. Maybe can help to somebody.

My version of curl was compiled with the Netscape Security System (NSS) libraries instead of the openSSL libraries. Versions of curl compiled with these two libraries use different certificate access methods. I was calling a flat file, which is the openSSL method. Another solution will be get NSS installed, (already there on most Red Hat derivatives) and create a cert9.db file, import your certificate and key (after converting to a P12 with openssl -don't forget to add a "freindlyName" or nickname) into that db using pk12util. Then you call the cert by it's nickname and give the password for the db.

The other option is get or compile a version of curl using the openssl libraries. RedHat 5, ubuntu or windows versions of curl are frequently already compiled that way. Red Hat 6 comes with curl compiled for NSS.


I also experienced this issue on RHEL 6. curl was compiled with NSS, which you can see by checking the version:

$ curl -V
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.3.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp 
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

The solution is to provide curl with a reference to the NSS database that stores the client certificate you want to use.

Create the certificate

I was starting from a Java keystore, which was created with this command (the alias value will be used to reference the certificate later):

keytool -genkeypair -alias myclient -keyalg RSA -keystore client_keystore.jks

Now, this JKS keystore needs to be converted to a pkcs12 format:

keytool -importkeystore -srckeystore client_keystore.jks \
    -destkeystore client_keystore.p12 -srcstoretype jks \
    -deststoretype pkcs12

Import the certificate into an NSS database

Next, create an NSS database in a directory of your choice:

mkdir /home/user/nss
certutil -N -d /home/user/nss

This certutil command creates 3 .db files, including cert8.db. This is the "old" db format but should still work. View the certutil documentation if you need to create a cert9.db file instead.

Use pk12util to import client_keystore.p12 into the NSS database

pk12util -i client_keystore.p12 -d /home/user/nss

Optionally, view the stored certificate in the database:

certutil -L -d /home/user/nss -n myclient

Use the certificate from curl

The certificate is now ready to be used by curl, but we need to let curl know where to find it. As specified in the curl manual, create an SSL_DIR environment variable:

export SSL_DIR=/home/user/nss

Finally, the curl command:

curl -vk --cert myclient https://localhost:8443/my/url

Note: the -k option is specified here because the server is using a self-signed certificate. See the curl manual for how to specify a cacert.

Remember to add the client certificate to the server's truststore if needed.

Reference

  • certutil and pk12util Documentation
  • Point curl to Firefox's NSS database (~/.mozilla/firefox/[profile])