Smart-card support in RHEL 8 and later

Updated -

In Red Hat Enterprise Linux, we strive to support several popular smart-card types. However, because it is not possible to support every smart card available, this document specifies our targeted cards. In addition it provides information on how to investigate a potential incompatibility between the cards and RHEL.

If you search for smart-card support for RHEL 7, see the Smart-card support in RHEL 7.4+ article.

Smart cards are typically handled on multiple layers and by multiple components, and for that we would like to provide a brief background to provide context for the following discussion.

On the lower level, the operating system communicates with the smart card reader, using the PC/SC protocol, and this communication is performed by the pcsc-lite daemon. The daemon forwards the commands received to the card reader typically over USB, which is handled by low-level CCID driver.

The PC/SC low level communication is rarely seen on the application level. The main method in RHEL for applications to access smart cards, is via a higher level API, the OASIS PKCS #11 API, which abstracts the card communication to specific commands that operate on cryptographic objects (private keys etc). Smart card vendors, often provide a shared module (.so file), which follows the PKCS #11 API, and serves as a driver for the card. That shared module can be imported by applications, and be used to communicate with the card directly. In the open source world, we have projects like OpenSC, which wraps several smart card drivers into a single shared module. For example the OpenSC module as shipped by RHEL8.0, provides support for Yubikey, Nitrokey, and the US-government PIV and CAC cards and many more, on a single module. We highly recommend smart card vendors to provide support for their cards using the OpenSC libraries.

Which cards are supported

In Red Hat Enterprise Linux 8 and newer, the following cards are supported:

  • All the cards targeted by Red Hat Certificate System (RHCS), i.e., CAC, PIV and cards with the CoolKey applet.
  • Selected PKCS#15 cards. While several cards of this family are supported, there are many different configurations and options for these cards; as such for special cards that may not be compatible with RHEL please contact your customer representative.
  • Other cards may be supported on Red Hat’s discretion.

Which card readers are supported

In Red Hat Enterprise Linux, we follow the pcsc-lite upstream project in regards to smart card reader hardware support. Most CCID compatible readers will work without any issue. Red Hat will periodically update the USB identifiers from the upstream project into our pcsc-lite-ccid driver. Furthermore, additional readers may be supported on Red Hat’s discretion. The following list of smart card readers are tested and verified by Red Hat:

  • SCR331/SCR3310
  • Omnikey 3121 ( must be part number R31210399 for the SC650 card )

The list of supported hardware in the upstream project.

Which PKCS#11 drivers are available

In RHEL8 and newer smart cards are accessed via the OpenSC PKCS#11 module. Note that for several cards which are supported in OpenSC’s upstream documentation that do not fall in one of the categories in the supported list above, Red Hat will provide ongoing assistance in a commercially reasonable manner.

Enabling new cards via OpenSC

Red Hat can enable new cards under the following conditions.

  • Newer cards can be enabled only during the Full Support Phase as documented in our support policy.
  • Sample hardware must be provided to Red Hat. One sample for Red hat engineering to enable the hardware and one sample for Red Hat Quality Engineering. This is a hard requirement and the submitted samples must be identical to the cards the customer will be using. If cards require provisioning with special non-generally available tools, then the provided cards must be provisioned.
  • Cards must conform to the support outlined above. That is, CAC, PIV, and cards with the CoolKey applet or PKCS#15 cards.

PKCS #11 URI

The PKCS#11 URI scheme is used to consistently identify smart cards, tokens and objects on them in the system. They are used by most of the tools in RHEL 8+ and simplify configuration of applications for smart cards. More information about supported applications and uses of the URI can be found in separate blog post.

Listing registered modules and objects

To list all system-wide registered PKCS#11 modules the following command can be used:

$ p11-kit list-modules

When working with applications using smart cards, it is often useful to know the URIs of the tokens or the objects stored in the token.
The identification URIs of registered PKCS#11 modules can be seen with the following command (this uses p11tool from gnutls-utils component).

$ p11tool --list-tokens

To list all certificates in a registered module the following command can be used:

$ p11tool --list-all-certs [URI]

Migrating from RHEL 7

RHEL 7 was originally shipped with CoolKey smart cards driver, which was deprecated and is no longer available in RHEL 8 and newer. The current driver OpenSC supports all cards that used to be supported by CoolKey. For more information, see the RHEL7 Smart Cards article.

Login in GNOME

Gnome in RHEL7 was relying on pam_pkcs11 to provide access to Smart Cards through NSS. In RHEL8+, the desktop login is managed by System Security Services Daemon (SSSD). How to configure system to allow smart cards login of users in IdM is described in RHEL 8 Product documentation, section Configuring Identity Management.

To configure a local user on a system non enrolled in IdM, there are few steps to go through:

  • Configure system using authselect (replaces authconfig in RHEL8+). For example:
authselect select sssd with-smartcard --force
  • Store the smart card CA file in /etc/sssd/pki/sssd_auth_ca_db.pem
  • In sssd.conf, enable pam_cert_auth = True in [pam] section
  • In sssd.conf, create a certificate mapping, for example (replace testuser with your username and with the appropriate certificate mapping):
[domain/shadowutils]
id_provider = files

[certmap/shadowutils/testuser]
matchrule = <SUBJECT>.*CN=testuser.*
  • Reboot

SSH login

OpenSSH in RHEL8 and newer supports PKCS #11 URIs as part of Consistent PKCS #11 support in RHEL8. In the past, configurations had to provide full path to the PKCS #11 shared object. This is no longer needed and minimal example to use private keys from smart cards with ssh requires the use of pkcs11: uri scheme:

$ ssh -i pkcs11: example.com

Smart cards in Firefox browser or Thunderbird

In RHEL7, the PKCS #11 modules had to be manually added to the Firefox NSS DB through the GUI. RHEL 8 and newer automatically loads all the PKCS #11 modules registered in p11-kit (see next section).

Register third party PKCS #11 module to p11-kit

RHEL 8+ is using system-wide registry of PKCS #11 modules for unifying access to cryptographic hardware. By default, only OpenSC PKCS #11 module is registered. If your smart card is not supported by OpenSC, but you have different PKCS #11 module, just create a new file under /usr/share/p11-kit/modules/ with the following syntax:

module: /path/to/example-pkcs11.so

Change the path /path/to/example-pkcs11.so to the location of your PKCS #11 module shared object. This will allow most of the system applications working with your smart cards.

Debugging smart card issues

As the smart cards go through several layers of abstraction, we need to identify the source of the problem first.

  • USB:
    • Is the token/reader detected in USB layer?
      • lsusb -v
  • PC/SC: pcsc-lite, pcsc-lite-ccid, pcsc-tools packages
    • Is the reader supported?
    • Is the card detected in PC/SC layer?
      • pcsc_scan
    • Generate PC/SC level trace (APDU messages exchanged)
      • sudo systemctl stop pcscd; sudo LIBCCID_ifdLogLevel=0x000F pcscd --foreground --debug --apdu --color | tee log.txt
  • PKCS#11: opensc package
    • Is the card detected in PKCS #11 layer?
      • pkcs11-tool -L
    • Can we list objects in the card?
      • pkcs11-tool -O
    • Can we login to the card?
      • pkcs11-tool --login -O
    • Run low-level PKCS #11 tests:
      • pkcs11-tool --test --login
    • Generate OpenSC debug log:
      • OPENSC_DEBUG=9 pkcs11-tool --test --login
  • Applications: sssd
    • Use debug_level = 9 in sssd.conf, restart sssd daamon and investigate logs under /var/log/sssd/

Q&A

I am using PIV card with OpenSC and I am prompted for a PIN with every signature. It didn’t happen with CoolKey in RHEL7

Every PIV digital signature key operation requires “explicit user action” as described in the following NIST document to assert reliable level of security. This requirement can be weakened by enabling PIN caching for these operation in OpenSC by setting pin_cache_ignore_user_consent in /etc/opensc-*.conf.

We are using only one type of the card and the detection takes too long.

The OpenSC implements support for most of the cards, but if you know that you will be using only one or two, it can be runtime configured in /etc/opensc.conf (on x86_64 architecture). In the section app default use the card_drivers option and set it to appropriate drivers you are interested in. You can list all the supported drivers using opensc-tool --list-drivers. For example to allow only CAC and PIV drivers, use the following configuration:

card_drivers = cac, PIV-II;

Our PIV cards have many certificates and its detection takes very long

If the card detection is still too slow after selecting only PIV driver, you can enable file caching of the certificate data by adding the following snippet to the framework pkcs15 section in /etc/opensc-*.conf:

use_file_caching = true;
file_cache_dir = /var/cache/mfa/;

Note, that the file_cache_dir needs to be accessible by the applications using smart cards, generally sssd's privileged process or any other application using pkcs11 module (Firefox, openssh, ...), depending on the use case. The directory should not be world-writable to prevent malicious users to tamper with this cache.
This was successfully tested with PIV cards, but should give performance improvement also for other card types.

Note, that this is a default since RHEL 8.4 (rhbz#1892810)

My smart card reader has a pinpad and I would like to use this feature to improve security

The OpenSC supports using pinpad readers, but some of the readers do not comply with the CCID specification so this functionality is turned off by default. You can enable pinpad on your reader by setting the enable_pinpad = true option in /etc/opensc.conf under the app default and reader_driver pcsc sections. If the pinpad needs pin of fixed length, it is possible to tweak it with the fixed_pinlength option.

Comments