cURL / Mailing Lists / curl-library / Single Mail

curl-library

CURLOPT_SSLENGINE and smartcard

From: Fletcher Liverance <fletcher.liverance_at_gmail.com>
Date: Wed, 18 Feb 2009 09:37:16 -0500

Hello,

I have a situation where I need to add smartcard support to an
application using libcurl with openssl. The requirement is to send the
client certificate from the smartcard along with a POST request to the
server. The smart card I'm using is an Aladdin eToken PRO 72k Java.
I'll be using pkcs11-helper from the opensc project to facilitate the
smart card side.

Normally this doesn't seem like it would be too difficult, I would
provide the client cert with CURLOPT_SSLCERT, provide the private key
with CURLOPT_SSLKEY and provide the key password with
CURLOPT_SSLKEYPASSWD.

However, in this case the private key is stored on the smart card and
cannot be extracted.

To get around this complication I've dynamically loaded the pkcs11
engine I need into openssl and set CURLOPT_SSLENGINE to 'pkcs11' which
is the dynamically loaded ssl engine for pkcs11 smartcards, also
provided by opensc. Next I believe I need to set CURLOPT_SSLKEYTYPE to
'ENG' and provide the "identifier passed to the engine" in
CURLOPT_SSLKEY.

Here's the code for what I'm trying to do:

curl_easy_setopt(curl, CURLOPT_SSLENGINE, "pkcs11");
curl_easy_setopt(curl, CURLOPT_SSLCERT, "/tmp/mypublic_cert.cer");
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "ENG");
curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, "password");
curl_easy_setopt(curl, CURLOPT_SSLKEY, "???");

They all return CURLE_OK, but curl_easy_perform returns the error
"problem with the local SSL certificate", and turning on
CURLOPT_VERBOSE yields "unable to use client certificate (no key found
or wrong pass phrase?)". Just to make sure I tested the key using
Aladdin's PKI client and the key was correct.

The fellows on the opensc mailing list said that I should be able to
handle it this way:
> does curl use openssl? then you could configure curl with engine_pkcs11
> to let the smart card handle the crypto. that way you need to pass the
> pin and the name of the pkcs#11 module to the enginine, and it will
> talk via that module to the card and use they rsa key on the card,
> without the key ever leaving the card.

That makes it sound like I'd just need to pass it SSLENGINE and
SSLKEYPASSWD, but that doesn't seem to work either, as I don't see any
messages from curl about using the engine/password or attaching the
certificate if I leave out CURLOPT_SSLCERT.

Does curl support allowing the smartcard to handle the private key in
this way, and is this the correct way to do it?

Second, what is the "identifier passed to the engine"? The libcurl
docs don't go into detail on it, and I haven't been able to find any
examples online of libcurl being used in this fashion.

Thanks,

Fletcher
Received on 2009-02-18