Linux smart card authentication – OpenSSL

(This is part of my howto on smart card authentication in Linux.)

You can use the private key stored on your card with OpenSSL, just like you would use an on-disk key. Among other things, you can sign files, decrypt files encrypted with your public key, or generate X.509 certificates for your key. Since this is not an OpenSSL guide, I will not describe those operations in detail, you can refer to the OpenSSL page in the Ubuntu Server Guide if you are not familiar with them, the syntax is the same (except for the necessary command flags to tell OpenSSL to use your smart card, see below).

First, install the package libengine-pkcs11-openssl. Then fire up the OpenSSL prompt and initialise the smart card engine with this long command (copy-and-paste is your friend):

firas@tsukino ~ % openssl
OpenSSL> engine dynamic -pre SO_PATH:/usr/lib/engines/ -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre
(dynamic) Dynamic engine loading support
[Success]: SO_PATH:/usr/lib/engines/
[Success]: ID:pkcs11
[Success]: LIST_ADD:1
[Success]: LOAD
Loaded: (pkcs11) pkcs11 engine

TODO: Is there a way to automate that?

You can now run the desired OpenSSL commands. To use the key stored on your smart card, you must add -keyform engine -engine pkcs11 to your command, and use slot_XX-id_YY as the value for the -key flag. You can get the slot number (to put instead of XX) with

firas@tsukino ~ % pkcs11-tool -L --module
Available slots:
Slot 0 (0xffffffffffffffff): Virtual hotplug slot
Slot 1 (0x1): Feitian SCR301 00 00
  token label:   Firas Kraiem (User PIN)
  token manuf:   EnterSafe
  token model:   PKCS#15
  token flags:   rng, login required, PIN initialized, token initialized
  serial num  :  2812504610040810

So my card is in slot 1. The value for YY is the ID of your key, as displayed in the output of pkcs15-tool -D.

For example, here’s how to generate a self-signed X.509 certificate (which will be useful also for PAM authentication, among other things):

OpenSSL> req -new -x509 -days 365 -keyform engine -engine pkcs11 -key slot_1-id_4eadab3c5ad2558770f25c344f4d553bb88812ef -out mysmartcard.cert.pem
OpenSSL> quit

You probably want to store the certificate on the card, this is done with the -X flag of pkcs15-init:

firas@tsukino ~ % pkcs15-init -X mysmartcard.cert.pem --auth-id 01 --id 4eadab3c5ad2558770f25c344f4d553bb88812ef --format pem
Using reader with a card: Feitian SCR301 00 00
User PIN [User PIN] required.
Please enter User PIN [User PIN]: 

As usual, replace ff with the Auth ID of the user, and 45 with the ID of the key.

6 thoughts on “Linux smart card authentication – OpenSSL

  1. David von Oheimb

    You can automate the engine definition by inserting in the openssl.cfg file before any section like [req] for instance this:

    openssl_conf = openssl_def

    engines = engine_section

    pkcs11 = pkcs11_section

    engine_id = pkcs11
    dynamic_path = /usr/lib/engines/
    MODULE_PATH = /usr/lib/
    init = 0

  2. Gabriel

    Hello and thank you for this useful articles. I have a token feitian epass3000 and I have on this some key pairs and an certificate x.509. I want to use this token to crypt and decrypt files but I don’t found yet the proper way to do this. Have you some suggestion for this? Command lines or an open application with GUI? I use the token with XCA application on Debian but I can not crypt and decrypt with this app. Thank you!

    1. Firas Post author

      I don’t knwo about XCA, but you can use OpenSSL as you normally would, after you have entered the commands to “activate” the card.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.