Smart card authentication

One of the most popular uses for smart cards is to control access to computer systems. The owner must physically have the smart card, and they must know the PIN to unlock it. This provides a higher degree of security than single-factor authentication (such as just using a password). In this page, we describe how to enable smart card authentication on Ubuntu.

Note

This guide is meant for Ubuntu Server 20.04 and newer. If you want to configure a desktop installation refer to the desktop guide.

Software requirements

The following packages must be installed to obtain a smart card configuration on Ubuntu:

  • pcscd: contains the drivers needed to communicate with the CCID smart card readers

  • opensc-pkcs11: (optional, depending on your smart card hardware) contains the smart card drivers, such as Personal Identify Verification (PIV) or Common Access Card (CAC)

  • sssd: the authentication daemon that manages smart card access and certificate verification

To install these packages, run the following command in your terminal:

$
sudo apt install opensc-pkcs11 pcscd sssd libpam-sss

Hardware requirements

Any PIV or CAC smart card with the corresponding reader should be sufficient. USB smart cards like Yubikey embed the reader, and work like regular PIV cards.

Each smart card is expected to contain an X.509 certificate and the corresponding private key to be used for authentication.

Smart card PKCS#11 modules

While opensc-pkcs11 supports a wide number of smart cards, some of them may require specific PKCS#11 modules, and you must refer to your vendor to install the proper one. From Ubuntu 20.04 LTS onward, all modules supported by p11-kit can be used.

If custom PKCS#11 modules are used, you need to ensure that p11-kit is properly configured.

In any case, p11-kit can be used to see all the configured modules that can be used for authentication:

$
p11-kit list-modules
p11-kit-trust: p11-kit-trust.so
    library-description: PKCS#11 Kit Trust Module
    library-manufacturer: PKCS#11 Kit
    library-version: 0.23
    token: System Trust
        manufacturer: PKCS#11 Kit
        model: p11-kit-trust
        serial-number: 1
        hardware-version: 0.23
        flags:
               write-protected
               token-initialized
opensc-pkcs11: opensc-pkcs11.so
    library-description: OpenSC smartcard framework
    library-manufacturer: OpenSC Project
    library-version: 0.20
    token: MARCO TREVISAN (PIN CNS0)
        manufacturer: IC: STMicroelectronics; mask:...
        model: PKCS#15 emulated
        serial-number: 6090010669298009
        flags:
               login-required
               user-pin-initialized
               token-initialized
               user-pin-locked

X.509 smart card certificates

The authentication is based on X.509 certificate validation and a smart card can provide one or more certificates that can be used for this purpose.

Before continuing, you may need to export or reference the certificate ID that must be used and associated to each user; such operations can be performed in one of the following three ways:

Using p11tool

This is a more generic implementation that just uses the PKCS#11 protocol so it should work with all modules:

$
sudo apt install gnutls-bin > p11tool --list-tokens

Alternatively, URLs can be listed via:

$
p11tool --list-token-urls
Token 1:
	URL: pkcs11:model=PKCS%2315%20emulated;manufacturer=IC%3A%20Infineon%3B%20mask%3A%20IDEMIA%20%28O...;serial=6090033068507002;token=MARCO%20TREVISAN%20%28PIN%20CNS1%29
	Label: MARCO TREVISAN (PIN CNS1)
	Type: Hardware token
	Flags: Requires login
	Manufacturer: IC: Infineon; mask: IDEMIA (O...
	Model: PKCS#15 emulated
	Serial: 6090033068507002
	Module: opensc-pkcs11.so

The command above will show all the available smart cards in the system and their associated PKCS#11 URI. Copy the URI token of the selected card in the following command, which prints all certificates that can be used for authentication and their associated token URIs.

$
p11tool --list-all-certs 'pkcs11:token=[TOKEN-ID]'

So in the above example:

$
p11tool --list-all-certs 'pkcs11:token=MARCO%20TREVISAN%20%28PIN%20CNS1%29'
Object 0:
	URL: pkcs11:model=PKCS%2315%20emulated;manufacturer=IC%3A%20Infineon%3B%20mask%3A%20IDEMIA%20%28O...;serial=6090033068507002;token=MARCO%20TREVISAN%20%28PIN%20CNS1%29;id=%02;object=CNS1;type=cert
	Type: X.509 Certificate (RSA-2048)
	Expires: ven 17 dic 2027, 00:00:00
	Label: CNS1
	ID: 02

Now, once the URI of the certificate that will be used for authentication is known, let’s extract the Common Name from the certificate. In the example we are assuming that our certificate URI is pkcs11:id=%02;type=cert.

It can be exported as text Privacy Enhanced Mail (PEM) format using:

$
p11tool --export 'pkcs11:id=%02;type=cert'

Using opensc

$
sudo apt install opensc

Certificates can be via: