Seamless Smartcard login with pam_pkcs11, and pam_krb5 against an Active Directory Domain using Red Hat Enterprise Linux 5 (Part 1)

Starting with Red Hat Enterprise Linux version 5 (RHEL 5), Red Hat added native support for PKI with pam_pkcs11, NSS, ccid, coolkey, and pcsc-lite. RHEL 5 also added rudimentary support for PKINIT in their Kerberos client, mostly based upon the CITI and Heimdal implementation (in pkinit-nss). Coming in a future update to RHEL 5 (maybe 5.3 or 5.4) you can expect better PKINIT support, with more MIT based PKINIT support.

This series of articles will cover how to configure a RHEL 5 system to allow users to log in with a smartcard, while also getting a Kerberos ticket from an Active Directory domain.

Part 1 will cover configuring NSS and OpenSSL. Part 2 will cover configuring pam_pkcs11 and testing a smartcard using the centralized NSS database. Part 3 will cover configuring Kerberos, PKINIT, and pam_krb5.

For the sake of simplicity, we are using our own Certificate Authority (CA), and not a third party. We will have only one root CA, and two intermediate CAs. All of the CA certificates are assumed to be in /root/CAs. All certificates are assumed to be in ascii (pem) format.

So, on with part 1…
[toc title=”Table of Contents”]

Configuring NSS and OpenSSL

Red Hat seems to be mostly moving away from using OpenSSL, and is now using NSS as their main crypto library; unfortunately, a lot of applications still use OpenSSL pretty heavily, so we’ll have to configure both NSS and OpenSSL. Thankfully, Red Hat centralized their PKI content into a centralized location: /etc/pki; this directory holds content for both OpenSSL and NSS.

Adding CA certs

Red Hat’s centralized NSS database holds no trusts by default. From a system security point of view, this is a good thing because PKI login will be limited only to the specific CAs that you trust. We’ll use certutil to add the CA certs to the central database in /etc/pki/nssdb:

certutil -A -n "Example Corp Root" -t "CT,C,C" -a -d /etc/pki/nssdb -i /root/CAs/examplecorprootclass2.crt

Let’s break down this command: “-A” tells certutil we want to add a certificate to the database. “-n” is used to give an alias to the certificate. “-t” tells certutil how to trust the certificate; this example may be overkill depending on how your CA is going to be used. You should normally only trust a certificate as much as actually needed. “-a” tells certutil the certificate we are adding is in ascii (pem) format. “-d” tells certutil what database we wish to add the certificate to. “-i” lists the certificate we wish to add.

You should repeat this command for every CA you have, changing the alias, trust level, and input file appropriately. To get an idea of the trust levels available, run the following:

certutil -H

To see a list of installed certificates run:

certutil -L -d /etc/pki/nssdb

Adding certificates to OpenSSL is easier. We’ll do three things:

  1. Drop the certificates into the /etc/pki/tls/certs directory
    • cp /root/CAs/*.crt /etc/pki/tls/certs
  2. Make hash links of the certificates
    • pushd /etc/pki/tls/certs; for i in `ls *.crt`; do [ ! -e $i.0 ] && ln -s $i $(openssl x509 -hash -noout -in $i).0; done; popd
  3. Make a bundle of the certificates
    • cat /root/CAs/*.crt > /etc/pki/tls/examplecom-bundle.crt

Check to ensure your smartcard library is in the NSS secmod database

For your system to access your smartcard, it’ll need to use a library to access it. Your NSS database may already have the library loaded as a module, but it is important to check. To check the loaded modules in NSS, use the modutil command:

modutil -list -dbdir /etc/pki/nssdb
Listing of PKCS #11 Modules
 1. NSS Internal PKCS #11 Module
 slots: 2 slots attached
 status: loaded

 slot: NSS Internal Cryptographic Services                            
 token: NSS Generic Crypto Services

 slot: NSS User Private Key and Certificate Services                  
 token: NSS Certificate DB

 2. CoolKey PKCS #11 Module
 library name:
 slots: 1 slot attached
 status: loaded

 slot: E-Gate 0 0

Notice above that the “NSS Internal PKCS#11 Module” and the “CoolKey PKCS #11 Module” modules are loaded. The NSS internal module is always loaded in NSS databases; the important module here is the CoolKey one. If a smartcard module isn’t loaded, you can load one with the modutil command:

modutil -add "CoolKey PKCS #11 Module" -libfile -dbdir /etc/pki/nssdb

You can use the full path to the library if you wish, but it isn’t necessary; furthermore, if you are scripting this, it’ll cause issues between different platforms.

This covers configuring NSS and OpenSSL; the next part in this series of articles will focus on pam_pkcs11.

Update (07/09/2009): Added information about checking NSS for smartcard libraries

  • Pingback: Using NSS with OpenSSH for Smart Card Login |

  • Bill

    When do I get to read about “CAC cards and Sun Directory Server 6”? Yup, the CAC is back… at the DoC. Yayyyyy…. :(

    • Never. It’s way better to do PKINIT against a Kerberos server, and use your Kerberos credentials for authenticating to Sun Directory Server. The certmap stuff in Sun Directory Server is painful with external CAs.

      It really doesn’t buy you much either. All you really get from it is the ability to do modifications against the directory using a smartcard. End-users log into systems without hitting LDAP directly when logging in with a smart card. For authentication, you only really need to hit LDAP to map their card to a username (and you don’t really even have to use LDAP for that).

      Honestly, if you don’t want to use Active Directory, FreeIPA is looking way nicer than Sun Directory Server; although, it doesn’t support PKINIT directly yet, and it isn’t on their radar.

    • So they are going the CAC route too? That should be fun ;). If you can access, I’d look into their CAC supported apps (PuttySC, InstallRoot for Linux, Firefox/Thunderbird CAC plugins, etc.).

      I think you can get PuttySC and the Mozilla stuff without going to…

  • Guy Zelck


    Fantastic job writing these articles on smart card login.
    I managed to get console and su authentication working on an Opensuse 11.2 distro.
    Particularly usefull to me was how to build up the nss database. This was key to making things work cause nothing was set up in my distro for this.

    A couple of things remain unclear to me :
    1. what to do with the CRLs? Are they also added to the nss database? If so, do you know how?
    2. my kdm and xdm login fails although the messages log says the authentication succeeded. Last line says : “getpwnam() failed.”

    Hope you can shed some more light on these.

    • There is a separate utility for adding CRLs, called crlutil. I don’t recommend using it, if you are using a Kerberos server that is checking the status of the certificates for you. If your Kerberos server is doing the checking, you are increasing the size of your nss database for little gain. If your Kerberos server is not checking the status of the certs, then you should use crlutil to add the CRLs, or use OCSP (OSCP is much better).

      I’ll get back to you on the kdm, and xdm login issues.

      • Guy Zelck

        Hi Ryan,

        Thx for the speedy response.

        I’m not using a Kerberos srv, rather I’m trying to use my company Activekey usb stick to authenticate myself.

        As you say, if uploading crls can be avoided, I’d rather take the OSCP route too. Is this accomplished by setting the cert_policy parameter to e.g. crl_auto in pam_pkcs11.conf or is there more to it?

        I found this CA that uses scripts to download the CRLs and then put them in the nss db and they too warn about possible corruptions (

        To add some info on the kdm pb : I found a reaction on the web from Ludovic Rousseau, one of the main developers in the opensc project, and according to him this is due to kdm. You can however fill in your userid in the usual field and the pin in the password field and it should work. I didn’t see this as in my config pam 1st tries the normal password authentication and then pkcs11, but my pin = my pwd so I thought I was logging in the old way.

        But I’m curious to learn what your research will reveal.

        Thx again,

        • You shouldn’t set the cert_policy parameter. If you set it to crl_auto, I believe it will download the CRLs every time someone tries to authenticate. I just realized this, but you only have the option to use OCSP if you are using Red Hat. They added a patch for it. Also, do your certificates list an OCSP server? If not, OCSP isn’t going to work.