Project

General

Profile

strongSwan smart card configuration HOWTO » History » Version 66

« Previous - Version 66/159 (diff) - Next » - Current version
Jean-Michel Pouré, 27.12.2009 11:46


strongSwan for Smartcards HOWTO

Smartcards are a mature technology which avoid your certificates from being stolen by a theft.

Introduction

GNU/Linux and other Unixes need two layers to be able to use smartcard readers:
  • OpenCT implements drivers for several smart card readers,
  • OpenSC libraries specify how to store cryptographic information on devices.

strongSwan relies on OpenSC to query the smartcard according to PKCS#11 RSA standard.
In this HOWTO, we give minimal information how to use a reader, initialize cards and use strongSwan.

Supported smartcard readers

Hardware requirements

OpenCT supports CCID compatible readers. All recent usb readers most likely implement the CCID specification and thus the generic USB CCID driver should work.

These Ominikey readers are quite popular:
  • Second hand Omnikey 3121 CardMan USB and Omnikey 4040 PCMCIA smartcard readers can be found on eBay for less than 10€.
  • Smartcard readers with an integrated PIN pad offer an increased security level because the PIN entry cannot be sniffed on the host computer e.g. by a surrepticiously installed key logger. The Omnikey 3821 secure smartcard reader with LCD display and keypad for secure PIN entry may be a good choice. It costs around 60 € new.
You also need blank cards:
  • Cryptoflex 32k are a common choice.

A list of supported card readers and smartcards can be found on OpenCT homepage.

Software requirements

To install pcsc-tools under Debian based distributions:

apt-get install pcsc-tools

If you own an Omnikey USB reader:

apt-get install pcsc-omnikey

strongSwan supports PKCS#11 RSA standard using opensc libraries, which specifies how to store cryptographic information on devices.

To install opensc:

sudo apt-get install opensc

Smartcard configuration

Certification Authority

We recommend using a certificate GUI to set-up your CA. One important thing to keep in mind is that, you shouldn't create private keys with a length not supported by your smart card (check the specs to be sure). Keys with a maximum length is 2048 bits are known to work.

Make a backup of your keys/certificates on a CD-ROM and store it in a safe place.

Initialisation of cards

Check that the card reader is correctly recognized by OpenSC:

$ opensc-tool -l
Readers known about:
Nr.    Driver     Name
0      pcsc       OmniKey CardMan 3121 00 00
1      openct     OpenCT reader (detached)
2      openct     OpenCT reader (detached)
3      openct     OpenCT reader (detached)
4      openct     OpenCT reader (detached)
5      openct     OpenCT reader (detached)

At nr. 0 we have our recognized Omnikey CardMan 3121 reader. Let's insert our smart card in the reader (note that when buying the card you'll also receive the TRANSPORT KEY. Make sure that the transport key proposed by OpenSC matches the one you got in the mail. You will destroy the card by entering the wrong Key three times):

Let's double check that the card is recongized by printing its ATR:

$ opensc-tool -r0 -a
3b:95:18:40:ff:62:04:01:01:05

We can also check the name of the card with the -n switch (we can omit the -r0 since we only have one reader connected):

$ opensc-tool -n
Cryptoflex 32K e-gate v4

At this point we know both the card and reader are fully recognized and functional, and we can proceed to erase the card: (You will be asked for the transport key you got in your mail)

The cost of a second hand reader with two blank cards is around 20€, so there is no reason to be interested in smartcards.
$ pkcs15-init -E

Transport key (External authentication key #1) required.
Please enter key in hexadecimal notation (e.g. 00:11:22:aa:bb:cc),
or press return to accept default.

To use the default transport keys without being prompted,
specify the --use-default-transport-keys option on the
command line (or -T for short), or press Ctrl-C to abort.
Please enter key [2c:15:e5:26:e9:3e:8a:19]:

Now we Initialize the card and we format it the PKCS#15 way. We will be prompted for Security Officer PIN, User Unblocking PIN (PUK) and Transport Key:

$ pkcs15-init --create-pkcs15
Please enter Security Officer PIN:
Please type again to verify:
Unblock Code for New User PIN (Optional - press return for no PIN).
Please enter User unblocking PIN (PUK):
Please type again to verify:
Transport key (External authentication key #1) required.
Please enter key in hexadecimal notation (e.g. 00:11:22:aa:bb:cc),
or press return to accept default.

To use the default transport keys without being prompted,
specify the --use-default-transport-keys option on the
command line (or -T for short), or press Ctrl-C to abort.
Please enter key [2c:15:e5:26:e9:3e:8a:19]:

Storing the private key on the card

Now we'll add a PIN for the label "Michele Baldessari" and we'll associate the 01 auth id to it. We'll be prompted for the Security Officer Pin inserted one step above :

$ pkcs15-init --store-pin --auth-id 01 --label "Michele Baldessari" 
New User PIN.
Please enter User PIN:
Please type again to verify:
Unblock Code for New User PIN (Optional - press return for no PIN).
Please enter User unblocking PIN (PUK):
Please type again to verify:
Security officer PIN required.
Please enter Security officer PIN:
Transport key (External authentication key #1) required.
Please enter key in hexadecimal notation (e.g. 00:11:22:aa:bb:cc),
or press return to accept default.

To use the default transport keys without being prompted,
specify the --use-default-transport-keys option on the
command line (or -T for short), or press Ctrl-C to abort.
Please enter key [2c:15:e5:26:e9:3e:8a:19]:

Now we can check the PINs stored on the card:

$ pkcs15-tool --list-pins
PIN [Security Officer PIN]
        Com. Flags: 0x3
        ID        : ff
        Flags     : [0xB2], local, initialized, needs-padding, soPin
        Length    : min_len:6, max_len:8, stored_len:8
        Pad char  : 0x00
        Reference : 2
        Type      : ascii-numeric
        Path      : 3f005015

PIN [Michele Baldessari]
        Com. Flags: 0x3
        ID        : 01
        Flags     : [0x32], local, initialized, needs-padding
        Length    : min_len:4, max_len:8, stored_len:8
        Pad char  : 0x00
        Reference : 1
        Type      : ascii-numeric
        Path      : 3f0050154b01

Now we'll store the client Certificate (stored in a PKCS#12 file name client-cert.p12) on the card and we associate it to auth-id 01, which we just created:

$ pkcs15-init -S client-cert.p12 -f PKCS12 -a 01
error:23076071:PKCS12 routines:PKCS12_parse:mac verify failure
Please enter passphrase to unlock secret key:
Importing 2 certificates:
  0: /C=IT/ST=Bozen/L=Sterzing/O=Foo/CN=Michele/emailAddress=michele@pupazzo.org
  1: /C=IT/ST=Bozen/L=Sterzing/O=Foo/CN=CA VPN/emailAddress=ca@pupazzo.org
Security officer PIN required.
Please enter Security officer PIN:
User PIN required.
Please enter User PIN:
Security officer PIN required.
Please enter Security officer PIN:

(We're asked for the PKCS#12 private key password, the Security Officer Pin and the User pin)

At this point we're set and the key is on the smartcard protected with a user pin from reading and with a security officer pin from writing.

You can double-check the certificates on the smart card with:

$ pkcs15-tool -c
X.509 Certificate [/C=IT/ST=Bozen/L=Sterzing/O=Foo/CN=Michele/emailAddress=michele@pupazzo.org]
        Flags    : 2
        Authority: no
        Path     : 3f0050154545
        ID       : 45

X.509 Certificate [/C=IT/ST=Bozen/L=Sterzing/O=Foo/CN=CA VPN/emailAddress=ca@pupazzo.org]
        Flags    : 2
        Authority: yes
        Path     : 3f0050154546
        ID       : 46

And the keys with:

$ pkcs15-tool -k
Private RSA Key [Private Key]
        Com. Flags  : 3
        Usage       : [0x2C], sign, signRecover, unwrap
        Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract, local
        ModLength   : 2048
        Key ref     : 0
        Native      : yes
        Path        : 3f0050154b0130450012
        Auth ID     : 01
        ID          : 45

strongSwan management

Configuration

To enable smart card support in strongSwan, you may need to compile from sources:

./configure <add your options there> \
--enable-smartcard
make
sudo make install

Defining a smartcard-based connection in ipsec.conf is easy:

    conn sun
         right=192.168.0.2
         rightid=@sun.strongswan.org
         left=%defaultroute
         leftcert=%smartcard
         auto=add

In most cases there is a single smartcard reader or cryptotoken and only one RSA private key safely stored on the crypto device. Thus usually the entry

    leftcert=%smartcard

which stands for the full notation

    leftcert=%smartcard#1

is sufficient where the first certificate/private key object enumerated by PKCS#11 module is used. If several certificate/private key objects are present then the nth object can be selected using

    leftcert=%smartcard#<n>

The command

    ipsec listcards

gives an overview over all certifcate objects made available by the PKCS#11 module. CA certificates are automatically available as trust anchors without the need to copy them into the /etc/ipsec.d/cacerts/ directory first.

As an alternative the certificate ID and/or the slot number defined by the PKCS#11 standard can be specified using the notation

    leftcert=%smartcard<slot nr>:<key id in hex format>

Thus

    leftcert=%smartcard:50

will look in all available slots for ID 0x50 starting with the first slot (usually slot 0) whereas

    leftcert=%smartcard4:50

will directly check slot 4 (which is usually the first slot on the second reader/token when using the OpenSC library) for a key with ID 0x50.

Entering the PIN code

Since the smartcard signing operation needed to sign the hash with the RSA private key during IKE Main Mode is protected by a PIN code, the secret PIN must be made available to Pluto.

For gateways that must be able to start IPsec tunnels automatically in unattended mode after a reboot, the secret PIN can be stored statically in ipsec.secrets

    : PIN %smartcard "12345678" 

or with the general notation

    : PIN %smartcard<nr> "<PIN code>" 

or alternatively

    : PIN %smartcard<slot nr>:<key id> "<PIN code>" 

On a personal notebook computer that could get stolen, you wouldn't want to store your PIN in ipsec.secrets.

Thus the alternative form

    : PIN %smartcard %prompt

will prompt you for the PIN when you start up the first IPsec connection using the command

    ipsec up sun

The ipsec up command calls the whack function which in turn communicates with Pluto over a socket. Since the whack function call is executed from a command window, Pluto can prompt you for the PIN over this socket connection. Unfortunately roadwarrior connections which just wait passively for peers cannot be initiated via the command window:

    conn rw
         right=%any
         rightrsasigkey=%cert
         left=%defaultroute
         leftcert=%smartcard1:50
         auto=add

But if there is a corresponding entry

    : PIN %smartcard1:50 %prompt

in ipsec.secrets, then the standard command

    ipsec rereadsecrets

or the alias

    ipsec secrets

can be used to enter the PIN code for this connection interactively. The command

    ipsec listcards

can be executed at any time to check the current status of the PIN code[s].

PIN-pad equipped smartcard readers

Smartcard readers with an integrated PIN pad offer an increased security level because the PIN entry cannot be sniffed on the host computer e.g. by a surrepticiously installed key logger. In order to tell pluto not to prompt for the PIN on the host itself, the entry

    : PIN %smartcard:50 %pinpad

can be used in ipsec.secrets. Because the key pad does not cache the PIN in the smartcard reader, it must be entered for every PKCS #11 session login. By default pluto does a session logout after every RSA signature. In order to avoid the repeated entry of the PIN code during the periodic IKE main mode rekeyings, the following parameter can be set in the config setup section of ipsec.conf:

    config setup
        pkcs11keepstate=yes

The default setting is pkcs11keepstate=no.

Configuring a smartcard with pkcsc15-init

strongSwan's smartcard solution is based on the PKCS#15 "Cryptographic Token Information Format Standard" fully supported by OpenSC library functions. Using the command

    pkcs15-init --erase-card --create-pkcs15

a fresh PKCS#15 file structure is created on a smartcard or cryptotoken. With the next command

    pkcs15-init --auth-id 1 --store-pin --pin "12345678" 
                --puk "87654321" --label "my PIN" 

a secret PIN code with auth-id 1 is stored in an unretrievable location on the smart card. The PIN will protect the RSA signing operation. If the PIN is entered incorrectly more than three times then the smartcard will be locked and the PUK code can be used to unlock the card again.

Next the RSA private key is transferred to the smartcard

    pkcs15-init --auth-id 1 --store-private-key myKey.pem
               [--id 45]

By default the PKCS#15 smartcard record will be assigned the ID 45. Using the --id option, multiple key records can be stored on a smartcard.

At last we load the matching X.509 certificate onto the smartcard

    pkcs15-init --auth-id 1 --store-certificate myCert.pem
               [--id 45]

The pkcs15-tool can now be used to verify the contents of the smartcard.

    pkcs15-tool --list-pins --list-keys --list-certificates

Acknowledgements

This article was adapted by Smartcard HOWTO written by Michele Baldessari. Permission granted by Michele Baldessari to reproduce the text on strongSwan wiki.