PAM-PKCS11 User Manual

Juan Antonio Martinez

Mario Strasser

Antti Tapaninen

Timo Sirainen

Ludovic Rousseau

Release 0.5beta2, 27 Sep 2005


Table of Contents

1. Copyright License
2. Introduction
3. Fundamentals
3.1. PKCS #11 Module Requirements
3.2. User Matching
4. Installation
5. Configuring pam-pkcs11
5.1. Setting up Configuration file
5.2. Setting up CRL's and CA's lists
5.3. Create map files
6. PAM Configuration
6.1. Configuring pam.d files
6.2. Sample pam.d/ entries
7. Using Login auto-detect features
8. Using the Event Manager Tools
8.1. Using the Card Event Manager
8.1.1. Structure of configuration file
8.2. Using the PKCS#11 Event Manager
8.3. Security issues
8.4. Example: use xscreensaver to lock screen on card removal
9. Using the Login Finder Tool
10. Using the PKCS#11 CertInspect tool
11. HOWTO install pam_pkcs11
11.1. Install the software
11.2. Configure pam_pkcs11
11.2.1. Create the needed directories
11.2.2. Copy and install the root CA certificate
11.2.3. Configure pam_pkcs11
11.2.4. Configure the subject mapper
11.3. Install and test your PAM configuration
11.4. Secure your PAM configuration
11.5. Using card_eventmgr
11.5.1. Configuring and testing card_eventmgr
11.5.2. Starting card_eventmgr
12. What is a cert mapper?
12.1. Fundamentals
12.2. Implementation of cert mappers in pam-pkcs11
12.3. How to use mapfiles
12.4. Mappers provided by Pam-pkcs11
12.4.1. Common Name (CN) mapper
12.4.2. Subject mapper
12.4.3. Getpwent() CN to login mapper
12.4.4. LDAP (lightweight directory access protocol) mapper
12.4.5. OpenSC library mapper
12.4.6. OpenSSH library mapper
12.4.7. Email Cert to login mapper
12.4.8. Microsoft Universal Principal Name mapper
12.4.9. Kerberos mapper
12.4.10. Unique ID to login mapper
12.4.11. Certificate Digest to login mapper
12.4.12. Generic mapper
12.4.13. Null mapper
12.5. Adding new mappers
13. Wish list
14. Contact

PAM-PKCS#11 is a PAM (Pluggable Authentication Module) library and related tools to perform login into Linux/UNIX systems by mean of X509 Certificates through any PKCS #11 compliant library.

This manual describes how to compile, install, configure and use pam-pkcs11 PAM module and related tools.

Chapter 1. Copyright License

Copyright (C) 2005 Juan Antonio Martinez

Copyright (C) 2003-2004 of Mario Strasser

ScConf library Copyright (C) Antti Tapaninen and Timo Sirainen

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Chapter 2. Introduction

pam_pkcs11 is a set of libraries and tools to controls the login process using a PKCS#11 token.

The Linux-PAM login module allows a X.509 certificate based user login. The certificate and its dedicated private key are thereby accessed by means of an appropriate PKCS #11 module. For the verification of the users' certificates, locally stored CA certificates as well as either online or locally accessible CRLs are used.

pkcs11_eventmgr is a tool to execute commands at insert or removal of a smart card from the reader. Alternatively, you can use the pcsc-lite's based version: card_eventmgr.

pkcs11_inspect tool allows you to look at the content of a certificate, in order to help you in the process of Certificate-to-User mapping configuration.

pklogin_finder tool can be used to check the PAM module without need to do the entire login process, just verifying that login names are properly found and matched.

Detailed information about the Linux-PAM system can be found in The Linux-PAM System Administrators' Guide, The Linux-PAM Module Writers' Guide and The Linux-PAM Application Developers' Guide.

The specification of the Cryptographic Token Interface Standard (PKCS #11) is available at PKCS #11 - Cryptographic Token Interface Standard.

Chapter 3. Fundamentals

Pam-pkcs11 is a PAM (Pluggable Authentication Module) pluggin to allow logging into a UNIX/Linux System that supports PAM by mean of use Digital Certificates stored in a smart card.

To do this, a PKCS #11 library is needed to access the Cards. Details on how certificates are stored/retrieved, etc are hidden to pam-pkcs11 and handled by PKCS #11 library. This allows independence of the module from a specific card.

3.1. PKCS #11 Module Requirements

The PKCS #11 modules must full-fit the requirements given by the RSA Asymmetric Client Signing Profile, which has been specified in the PKCS #11: Conformance Profile Specification by RSA Laboratories.

3.2. User Matching

To approve the ownership of a certificate, that is, to allow the owner of a certificate to login as a particular user, pam-pkcs11 uses several modules called mappers that perform cert-to-login mapping. See Chapter 12, What is a cert mapper? section.

[Note: This is still a work in progress, any suggestions for improvements or alternative matching algorithms are welcome.]

Chapter 4. Installation

  1. Download source code from the official site.
  2. Unpack source tarball:
    tar xvzf pam_pkcs11-X.Y.Z.tar.gz
    cd pam_pkcs11-X.Y.Z
    
  3. If using SVN tree, re-create environment:
    ./bootstrap
    
  4. Execute the "standard" install sequence :-)
    ./configure
    make
    make install
    
  5. Alternatively, on RedHat Linux systems, you can use rpmbuild tools and the provided .spec file to create and install RPM packages:
    rpmbuild -ta /path/to/pam_pkcs11.X.Y.tar.gz
    rpm -v -i /usr/src/redhat/RPMS/i386/pam_pkcs11-X.Y-Z.i386.rpm
    rpm -v -i /usr/src/redhat/RPMS/i386/pam_pkcs11-tools-X.Y-Z.i386.rpm
    
  6. Configure package:
    1. Create the base configuration directory: /etc/pam_pkcs11/
    2. Copy ${base}/etc/pam_pkcs11.conf.example to /etc/pam_pkcs11/, rename it to /etc/pam_pkcs11/pam_pkcs11.conf and personalize it
    3. Create /etc/pam_pkcs11/crls/ and /etc/pam_pkcs11/cacerts/ directories corresponding to the configuration file, and fill them with proper data. The tools/ directory provides a tool pkcs11_make_hash_link that can be used to create hash files on every valid Cert and CRL file.
    4. Choose one or more mappers to install, set up configuration file, and if needed configure mappers. File /etc/pam_pkcs11.conf is documented to allow an easy editing
    5. Edit and configure /etc/pam.d/xxx entries. See instructions bellow
    6. Use pkcs11_inspect and pklogin_finder provided tools to see if you can read certificate data and perform correct user mapping
    7. Try to log in. For instance, switch to a new tty console
  7. If things go wrong:
    • Ensure that the PKCS #11 library works properly. You can, for instance, try to use the PKCS #11 module as an engine for OpenSSL or Mozilla/Firefox
    • Re-check the configuration
    • If a mapping file is used, check it. There are some known problems on some certificates that uses obscure character encodings (non utf-8), that makes CN mappings fail

NOTES

  • To avoid locking the computer, it is recommended to try to configure only one non-critical service the first time (e.g. /etc/pam.d/xscreensaver), and allow normal login on the other services (/etc/pam.d/gdm).
  • PAM modules used for remote authentication (e.g. /etc/pam.d/sshd) cannot be used with pam-pkcs11 since there is no local smart card on the server. To do remote logging, you should use a kind of Single Sign On (SSO) service (Kerberos, winbind, etc.) and authenticate against a local (client) smart card. This is a job in progress.

Chapter 5.  Configuring pam-pkcs11

Configuration of pam-pkcs11 involves two steps:

  1. Configure pam-pkcs11
  2. Configure global PAM options

This chapter explains pam-pkcs11 configuration-related issues. Next chapter deals with generic PAM options. You should read this manual and study the provided configuration sample files before doing any change.

You must know:

  • Which PKCS #11 module you are going to use, and its filename
  • Which mapper(s) module(s) you need, and if needed, how to create and edit related mapping files
  • You'll also need the root Certificate Authority files, and if required, the Certificate Revocation Lists ones
  • Of course, the list of authorized users to login, and their corresponding certificates. When a remote certificate authentication is performed (e.g., via LDAP, ADS or NSS), this information must reside on, or be accessible by the server

5.1. Setting up Configuration file

The configuration file uses the scconf library.

Parameters and data are grouped into blocks. Blocks can be nested in a tree.

A pam-pkcs11 configuration file looks like:

pam-pkcs11 {
	global options
	...
	use_pkcs11_module = pkcs11 module to be used

	pkcs11_module module1 {
		module1 specific options
	}

	pkcs11_module module2 {
		module2 specific options
	}

	[...]

	use_mappers = mapper1, mapper2,... ; 

	mapper mapper1 {
		mapper1 specific options
	}

	mapper mapper2 {
		mapper2 specific options
	}

	[...]
	mapper mapperN {
		mapperN specific options
	}
}

For detailed description see the pam_pkcs11.conf.example file.

Details on scconf syntax and API are provided in the src/scconf/README.scconf file.

5.2. Setting up CRL's and CA's lists

pam-pkcs11 needs a list of recognized Certificate Authorities, to properly validate user certificates. The same applies to Certificate Revocation Lists (if configured to be used).

So the process to setup ca and crl entries is:

  1. Create ca_dir and crl_dir directory entries, according to configuration file
  2. Copy CA Certificates (either DER or PEM format) to the ca_dir directory
  3. Create hash links to CA certificates with provided pkcs11_make_hash_link. Note that OpenSSL must be installed
    cd /etc/pam_pkcs11/cacerts
    /usr/bin/pkcs11_make_hash_link
    
  4. Repeat above procedure for CRL entries (if used)
  5. Select your Certificate verification policy ("cert_policy" option in "module" entry)

NOTE: Due to OpenSSL library limitations, CA root certificate entries must reside in the local file system, and cannot be accessed from a remote server. So although user auth can be done in a remote way, certificate trust chain validation must be done locally.

5.3. Create map files

If your selected mapper module(s) use(s) login mapping, you'll need to create and setup mapping files. Some examples are provided with the source code.

As a general rule, a mapping file has a new line terminated list of certificate contents -> login entries:

Certificate1 data -> login1
Certificate2 data -> login2
Certificate2 data -> login3

Remember that this file is parsed from the first line to the end, and returns on the first match.

As you can see bellow, mapfile specification doesn't need to be a regular file: you can retrieve data from any legal URL. Anyway, data format must be preserved. See Section 12.3, “How to use mapfiles” for additional info.

Chapter 6. PAM Configuration

6.1. Configuring pam.d files

To make use of the PKCS #11 login module add the line

auth	sufficient	pam_pkcs11.so	...

in the /etc/pam.d/serviceXXX configuration file.

Some mappers doesn't map to an existing user. To allow correct login, you may need to install also pam-mkhomedir in session PAM stack See http://www.kernel.org/pub/linux/libs/pam for details.

The following options are recognized by pam-pkcs11.so:

debug
Enable debugging support.
err_display_time
Seconds to wait after error message is shown to give users a chance to read the message.
config_file
To specify up configuration file (default /etc/pam_pkcs11/pam_pkcs11.conf)

The next options should be taken from the configuration file (default /etc/pam_pkcs11/pam_pkcs11.conf), but is up to the user to specify them in the command line. If so, it takes precedence over the configuration file.

nullok
Allow empty passwords.
use_first_pass
Do not prompt the user for the passwords but take them from the PAM_ items instead.
try_first_pass
Do not prompt the user for the passwords unless PAM_(OLD)AUTHTOK is unset.
use_authtok
Like try_first_pass, but fail if the new PAM_AUTHTOK has not been previously set (intended for stacking password modules only).

Next options are PKCS #11 module specific:

pkcs11_module=<file>

Filename of the PKCS #11 module. The default value is /etc/pam_pkcs11/pkcs11_module.so

Note that this option takes precedence over "module" entry in proper pkcs11_module section, but this section is still needed

slot_num=<nr>

Slot-number to use: 1 for the first, 2 for the second and so on. The default value is 0, which means to use the first slot with an available token.

ca_dir=<path>

Path to the directory where the CA certificates are stored. The directory must contain an OpenSSL hash-link to each certificate. The default value is /etc/pam_pkcs11/cacerts/.

Pam-pkcs11 provides a utility: pkcs11_make_hash_link that can be used to create hash links to certificate files. Hashes are used to check certification validity and revocation.

crl_dir=<path>

Path to the directory where the CRLs are stored. The directory must contain an openssl hash-link to each CRL. The default value is /etc/pam_pkcs11/crls/.

cert_policy={none, ca, signature, crl_online, crl_offline, crl_auto}

Sets the Certificate verification policy:

  • none: Performs no verification at all
  • ca: Checks that Certificate has a recognized CA from ca_dir
  • signature>: Does a signature check to ensure that private and public key matches
  • crl_online: Downloads the CRL from the location given by the CRL distribution point extension of the certificate
  • crl_offline: Uses the locally stored CRLs.
  • crl_auto: Is a combination of online and offline: it first tries to download the CRL from a possibly given CRL distribution point and if this fails it uses the local CRLs.

You can use a comma-separated list to specify all desired options, eg ca,crl_offline,signature. The default setting is none.

6.2. Sample pam.d/ entries

Here is the normal way to use pam-pkcs11 into the PAM stack. Only the first auth line is added. You configuration may be different depending on your Unix system.

#%PAM-1.0
auth       sufficient   pam_pkcs11.so
auth       required     pam_securetty.so
auth       required     pam_stack.so service=system-auth
auth       required     pam_nologin.so
account    required     pam_stack.so service=system-auth
password   required     pam_stack.so service=system-auth
session    required     pam_stack.so service=system-auth
session    optional     pam_console.so

An alternate way is to use explicit options. This is not recommended, but still possible:

#%PAM-1.0
auth       sufficient    pam_pkcs11.so	nullok debug try_first_pass \
             config_file=/etc/pam_pkcs11/pam_pkcs11.conf \
             pkcs11_module=/usr/lib/pkcs11/pkcs11_module.so \
             ca_dir=/etc/cacerts/ crl_dir=/etc/cacerts/ cert_policy=none
auth       required     pam_securetty.so
auth       required     pam_stack.so service=system-auth
auth       required     pam_nologin.so
account    required     pam_stack.so service=system-auth
password   required     pam_stack.so service=system-auth
session    required     pam_stack.so service=system-auth
session    optional     pam_console.so

In this second example the configuration file is still needed to get the mapper module options and flags.

Chapter 7. Using Login auto-detect features

Starting at pam_pkcs11-0.4.2 a new feature is provided: pam-pkcs11 can deduce the username from the user certificate without using the login prompt.

This is done when pam_get_user() call returns null or an empty string. In this case, pam-pcks11 uses the module mapper "find" feature instead of normal "match".

If the finder returns with success, the found username is set to PAM using pam_set_item(PAM_USER) call, and PAM_AUTH_OK is returned.

So it is no longer needed to enter the login name if a certificate is provided and can be mapped to a user.

There are to ways for using this feature:

  1. Patch "gdm" and "login" programs to detect card presence and return null as user name, without prompt for a user login. This is a work to be done :-(
  2. Use unpatched versions, and do the following procedures:
    1. When login from console, just enter " " (space) + Enter.
    2. When login from gdm, just key Enter at login prompt.

In both cases the procedure follows as:

  1. If a card is not present, "login" will ask for a password and then fail; "gdm" will prompt again for a user login
  2. If a card is present, pam-pkcs11 will ask for the PIN, and then invoke finder in module mapper list. When a user is found, this user become the logged user

This feature can be used with pam-mkhomedir.so PAM session module. In this case, you can create on-the-fly accounts. This scenario is ideal for centralized auth services (Winbind, LDAP, Kerberos, RDBMS auth...).

As example, here comes my tested /etc/pam.d/gdm file:

#%PAM-1.0
auth       sufficient   pam_pkcs11.so debug config_file=/etc/pam_pkcs11/pam_pkcs11.conf
auth       required     pam_env.so
auth       required     pam_stack.so service=system-auth
auth       required     pam_nologin.so
account    required     pam_stack.so service=system-auth
password   required     pam_stack.so service=system-auth
session    required     pam_stack.so service=system-auth
session    optional     pam_mkhomedir.so skel=/etc/skel umask=0022
session    optional     pam_console.so

IMPORTANT NOTES: For pam_set_item(PAM_USER) to succeed, the application using PAM must have enough permission. If this condition is not met, setting user process will fail and proper log message registered. So this feature is mainly provided for logging processes running as root.

Improper mapper chain' configurations with unauthorized certificates can lead to the creation of fake accounts in the system if pam_mkhomedir.so module is used. So be really careful when authenticate users directly from certificates.

Chapter 8. Using the Event Manager Tools

PAM-PKCS11 includes several tools: card_eventmgr and pkcs11_eventmgr that can be used to monitor the status of the card reader and dispatch actions on several events. These programs can be used to several actions, like lock screen on card removal.

Note that these programs have no direct interaction with pam-pkcs11 module: they are just card status monitors. It is the system administrator job to define and configure actions to take on events.

8.1. Using the Card Event Manager

card_eventmgr is a card status monitor based on the PCSC-Lite library.

To invoke the program, just type card_eventmgr. Several command lines options are recognized:

  • debug to enable debugging. Default is no debug
  • daemon to run as a daemon in the background. If debug is unset, also detach from the tty. Default is to run in the foreground
  • timeout=<msecs> time in milliseconds between two consecutive status poll. Defaults is 1000 (1 second)
  • config_file=<file> configuration file to use. Default is /etc/pam_pkcs11/card_eventmgr.conf

8.1.1. Structure of configuration file

Here is an example of configuration file. It is auto-descriptive:

card_eventmgr {

	# Run in background? Implies debug=false if set to true
	daemon = false;

	# show debug messages?
	debug = false;

	# polling time in milliseconds
	timeout = 1000;

	#
	# list of events and actions

	# Card inserted
	event card_insert {
		# what to do if an action fail?
		# ignore  : continue to next action
		# return  : end action sequence
		# quit    : end program
		on_error = ignore ;

		# You can enter several, comma-separated action entries
		# they will be executed in turn
		action = "/usr/bin/play /usr/share/sounds/warning.wav",
			"/usr/X11R6/bin/xscreensaver-command -deactivate";
	}

	# Card has been removed
	event card_remove { 
		on_error = ignore;
		action = "/usr/bin/play /usr/share/sounds/error.wav",
			"/usr/X11R6/bin/xscreensaver-command -lock";
	}
}

8.2. Using the PKCS#11 Event Manager

pkcs11_eventmgr is very similar to card_eventmgr, with some improvements:

  1. It uses the PKCS#11 library, instead the low-level PCSC-Lite API
  2. Polling time, and expire time unit is the second, not the millisecond
  3. New command line options:
    • [no]debug to enable/disable debugging. Defaults to "nodebug"
    • [no]daemon to run as daemon or foreground. If debug is unset, daemon mode also detaches from tty. Default to "nodaemon"
    • polling_time=<secs> time in seconds between two consecutive status poll. Defaults to 1 second
    • expire_time=<secs> time in second on card removed to trigger "expire_time" event. Default to 0 (no expire)
    • config_file=<file> configuration file to use. Defaults to /etc/pam_pkcs11/card_eventmgr.conf
    • pkcs11_module=<file> PKCS #11 dynamic library to use. Defaults to /usr/lib/pkcs11/opensc-pkcs11.so
  4. Expire time on card removal is now supported
  5. Configuration file is slightly different. See provided example

Here is a pkcs11_cardmgr sample file, with defaults

# Sample pkcs11_eventmgr configuration file
#
pkcs11_eventmgr {

	# Run in background? Implies debug=false if true
	daemon = true;

	# show debug messages?
	debug = false;
	
	# polling time in seconds
	polling_time = 1;

	# expire time in seconds
	# default = 0 (no expire)
	expire_time = 0;
	
	# pkcs11 module to use
	pkcs11_module = /usr/lib/opensc-pkcs11.so;

	#
	# list of events and actions

	# Card inserted
	event card_insert {
		# what to do if an action fail?
		# ignore  : continue to next action
		# return  : end action sequence
		# quit    : end program
		on_error = ignore ;

		# You can enter several, comma-separated action entries
		# they will be executed in turn
		action = "/usr/bin/play /usr/share/sounds/warning.wav",
			 "/usr/X11R6/bin/xscreensaver-command -deactivate";
	}

	# Card has been removed
	event card_remove { 
		on_error = ignore;
		action = "/usr/bin/play /usr/share/sounds/error.wav",
			 "/usr/X11R6/bin/xscreensaver-command -lock";
	}

	# Too much time card removed
	event expire_time { 
		on_error = ignore;
		action = "/bin/false";
	}
}

As you can see, on each event you can define a list of actions, and what to do if an action fails.

8.3.  Security issues

The best way to start card monitoring is at user login. If so, note that all event commands will be executed with user privileges. So it is up to the user to take care that he has permissions to execute the desired actions.

Special checks should be done when invoking setuid/segid programs: these commands usually ignore the user environment and set up their own. So these applications may not work as expected.

Command actions are executed via execve("/bin/sh","-c","provided command",null,environ) in order to avoid security risks if using system() library call.

8.4.  Example: use xscreensaver to lock screen on card removal

Just add to your ~/.xsession or KDE/GNOME Autostart directory an invocation to card_eventmgr in daemon mode. Your ~/.xsession should look like: FIXME

Additionally you can add this line to /etc/pam.d/xscreensaver configuration file:

auth       sufficient   pam_pkcs11.so

In this case, when card is removed the X screen will lock. When card is re-inserted, screen will prompt for the card PIN, check it and if access granted the screen will unlock

NOTES:

  1. Starting pam_pkcs11-0.4.4, card_eventmgr tool is no longer supported by pam-pkcs11, and may be removed in newer versions on the package. Users are encouraged to upgrade to pkcs11_eventmgr. This is done to avoid dependencies on low level card management routines
  2. Some PKCS#11 implementations do not properly support C_WaitForSlotEvent() function as defined in PKCS #11 v2.1 API. So current pkcs11_eventmgr doesn't use it at all, just sleep+rescan tokens. This is a time-consuming behavior, and may change in future versions of the tool

Chapter 9. Using the Login Finder Tool

PAM-PKCS#11 provides another tool: pklogin-finder that can be used to find Cert-to-login maps, outside the PAM environment. This tool can be used to create and test map files, or to check environment and configuration files, without need to use PAM related tools.

pklogin_finder uses the same structure and configuration than pam-pkcs11 module. It reads certificate, and try all specified mappers to find a user match. When found, login name is displayed on stdout.

To invoke, just type from console:

pklogin_finder [[no]debug] [config_file=<file>]

By default, debug is set to false, and config_file to /etc/pam_pkcs11/pam-pkcs11.conf. All PAM related options (nullok, try_first_pass, and so) in configuration file are ignored

Return values are:

  • 0 0n success, and login name displayed on stdout
  • 1 On no login match found
  • 2 On process error

Chapter 10. Using the PKCS#11 CertInspect tool

Starting at version 0.5 a new tool pkcs11_inspect is provided.

pkcs11_inspect is a PKCS #11 based tool to explore certificate contents. It's similar to pklogin_finder, but no mapping is done at all: just load mappers' chains, and in turn, try to get proper data from certificate (i.e.: cn_mapper looks for CN entries, and so).

When desired info is found, pkcs11_inspect print found data to stdout, without doing any mapping, that is, mapfile entries in configuration file are ignored.

The reason to exist for this tool is to ease the making of mapping files:

  • Insert your smart card
  • Invoke pkcs11_inspect
  • Store result as "left side" of mapfile
  • Edit mapfile and assign contents to a login

Same command line options and configuration file than pklogin_finder applies to pkcs11_inspect command, but note that mapping and ignorecase options will be ignored. See the manual page for details.

Chapter 11. HOWTO install pam_pkcs11

We will now describe a complete installation of pam_pkcs11 as an example case. This configuration will use a local root CA certificate and the subject mapper. Many other configurations are also possible.

11.1.  Install the software

You should install pre-compiled binaries since that is the easiest way to install a software. See the documentation of your distribution to know how to install RPM, DEB or whatever packages.

If you want to recompile from source read Chapter 4, Installation.

11.2.  Configure pam_pkcs11

11.2.1.  Create the needed directories

mkdir /etc/pam_pkcs11
mkdir /etc/pam_pkcs11/cacerts
mkdir /etc/pam_pkcs11/crls

11.2.2.  Copy and install the root CA certificate

I used tinyCA to generate the root CA and the user certificates. Your root CA certificate name may be different. Make sure that all the files in /etc/pam_pkcs11/cacerts/ can be read by any user.

cp testCA-cacert.der /etc/pam_pkcs11/cacerts/
cd /etc/pam_pkcs11/cacerts
chmod a+r *
pkcs11_make_hash_link

11.2.3.  Configure pam_pkcs11

Copy the sample file:

cp /usr/share/doc/pam-pkcs11/examples/pam_pkcs11.conf.example.gz /etc/pam_pkcs11/
cd /etc/pam_pkcs11/
gunzip pam_pkcs11.conf.example.gz
mv pam_pkcs11.conf.example pam_pkcs11.conf

The sample file uses the OpenSC PKCS#11 library. You may need to edit /etc/pam_pkcs11/pam_pkcs11.conf if you want to use another PKCS#11 library.

11.2.4.  Configure the subject mapper

Copy the sample file:

cp /usr/share/doc/pam-pkcs11/examples/subject_mapping.example /etc/pam_pkcs11/subject_mapping

Then use pkcs11_inspect to get the information you need for the mapper. In our case you are looking for something like:

Printing data for mapper subject: /C=ES/O=FNMT/OU=FNMT Clase 2
 CA/OU=500051483/CN=NOMBRE MARTINEZ CASTA\xF1O JUAN ANTONIO
 - NIF 50431138G

Note that this is one line but it is wrapped to be displayed here in the form of three lines.

Then edit /etc/pam_pkcs11/subject_mapping to add the strings above followed by -> login name. The file should then contain something like:

# Mapping file for Certificate Subject
# format: Certificate Subject -> login
#
/C=ES/O=FNMT/OU=FNMT Clase 2 CA/OU=500051483/CN=NOMBRE MARTINEZ
CASTA\xF1O JUAN ANTONIO - NIF 50431138G -> jantonio

Again note that the two last lines displayed should be only one.

11.3.  Install and test your PAM configuration

You will now configure your PAM system to use pam_pkcs11. We recommend you to start with an easy-to-debug application like login. The advantage of login is that you can see the debug messages from pam_pkcs11.

Edit /etc/pam.d/login and add, at the beginning of the file, the lines:

# pam_pkcs11: smart card login
auth       sufficient pam_pkcs11.so

Since /etc/pam_pkcs11/pam_pkcs11.conf has "debug = true" you should see lots of debug on the console you use to log in. You should also see any error that would occur. If everything works correctly you can change the configuration file and use "debug = false".

Once your PAM configuration is tested and working you can configure all the PAM applications you want to use with a smart card. A possible list is:

  • gdm (Gnome Display Manager)
  • kdm (KDE Display Manager)
  • xdm (X11 display manager)
  • login (text console login)
  • xscreensaver (X11 screen saver)
  • etc.

11.4.  Secure your PAM configuration

We used "sufficient" in the PAM configuration file. If the pam_pkcs11 module fails to authenticate the user the PAM system will go on with the next PAM module, the next PAM module should ask for a password. If you want to use the smart card only and not the password any more just replace "sufficient" by "required". The authentication process will then fail if pam_pkcs11 fails.

Note: with the "required" option, if there is a bug in any smart card related software you will not be able to log in even as root. It should be safer to keep the possibility to log in using a password but at the same time disable password login for normal users. So you will still be able to login as root with the root password.

11.5.  Using card_eventmgr

card_eventmgr is a helper tool to automatically launch an application to lock or unlock the screen when the card is removed or inserted. A natural application is to lock the X11 screen when the card is removed.

11.5.1.  Configuring and testing card_eventmgr

Copy the sample file:

cp /usr/share/doc/pam-pkcs11/examples/card_eventmgr.conf.example /etc/pam_pkcs11/card_eventmgr.conf

Edit the configuration file to set the actions to be processes when the card is removed and inserted. You may have to change the command to play a sound.

You can now test your card_eventmgr configuration file by executing

card_eventmgr debug nodaemon

You will see some debug messages and, possibly, why the command you configured as action does not work properly.

11.5.2.  Starting card_eventmgr

After debugging your card_eventmgr configuration file you can start it automatically. One solution is to create a ~/.xsession file containing:

# start the card autolock
card_eventmgr pidfile=$HOME/.card_eventmgr.pid

# start Gnome or something else
/usr/bin/x-session-manager

# kill the card autolock
card_eventmgr kill pidfile=$HOME/.card_eventmgr.pid

Chapter 12. What is a cert mapper?

12.1.  Fundamentals

When a X509 Certificate is provided, there are no direct ways to map a cert to a login. With a certificate we can check validity and revocation, but user mapping depends entirely on certificate contents.

So we need a configurable, stackable, and definable way to specify cert-to-user mapping.

pam-pkcs11 cert mappers provides several functions to:

  1. Search an specific item in certificate
  2. Deduce a login from certificate
  3. Test if a login and a certificate matches

Normal pam-pkcs11 login process involves following procedures:

  1. Enter login
  2. Ask for PIN
  3. Open and validate certificate
  4. Map certificate into an user (*)
  5. Check if login and user matches (**)

An alternate way of working is by mean of not providing user name:

  1. Detect if a card is inserted
  2. Ask for PIN
  3. Open and validate certificate
  4. Map certificate into an user (*)
  5. Open session for deduced login

Last way needs an additional pam-mkhomedir.so PAM module, which can dynamically create an account.

Operations (*) and (**) are the reason for cert-mappers to exist.

12.2. Implementation of cert mappers in pam-pkcs11

pam-pkcs11 implements cert mapper in form of dynamic loaded modules. Additionally, most of simplest mappers doesn't need to be dynamically loaded, as they are already statically linked with pam-pkcs11. You can add as many modules as desired, and the system will try all of them in turn, until match is done, or end of list get reached.

The mapper list is defined in the configuration file:

pam-pkcs11 {
....
    use_mappers = mapper1 [ [[,] mapper2 ] ... ] ;
    ....
    mapper mapper1 {
	debug = false;
	# When the mapper module is to be dynamically loaded, specify path
	module = /path/to/module.so;
	# When the mapper module is statically linked set to "internal"
	# module = internal;
	[ additional mapper dependent options ]
    }
    ....
}

"module" option is mandatory: says pam_pkcs11 where to find dynamic library. Additional entries can be defined but are module dependent

12.3. How to use mapfiles

Most of mappers supports the concept of mapfile, that is, a system to convert a given certificate data item to a user login. The reasons are simple:

  • Most certificate contents are no valid for use as login name, and need some way to manage it
  • We can store and manage a list of authorized certificates in a centralized way

The mapfile scheme used in pam-pkcs11 is powerful: it's not only restricted to files, so we can specify HTTP, LDAP, FTP and so connections, to retrieve mapfile. So this scheme is ideal for centralized accounting systems.

The common structure of all mapfiles is:

Certificate 1 entry data -> login1
Cert 2 data -> login2
string from -> string to

That is: a string, the sequence " -> " (space, dash, greater, space) and a login

NOTE: It's syntactically correct to specify more than one word in the right side of a map entry. But be aware that most mappers expect to be returned a single word that provides a user login. Otherwise a strange behavior may occur. See specific notes on mappers.

When a mapper module uses mapfiles, has a structure like:

...
mapper my_mapper {
	...
	mapfile = URL;
}
...

URL is a Universal Resource Locator as defined in corresponding RFC:

  • ftp://user:password@my.host.com/file
  • file:///path/to/local/file
  • https://www.weirdserver.com:8000/
  • ldap://ldap.frontec.se/o=frontec??sub?mail=*sth.frontec.se

Note that depending on compile time options pam-pkcs11 may not support all URL syntax. See Install section and use of --use-curl configure option

Provided source code includes several example mapping files

12.4. Mappers provided by Pam-pkcs11

The standard pam-pkcs11 provides following mapper modules:

12.4.1. Common Name (CN) mapper

Assumes CN field on certificate to be the login name.

  • When used as finder, module returns the first CN field found or NULL
  • When used as matcher, it parses certificate and compare all CN fields found against provided login name, returning OK if match found

In either case, if a mapfile is used, the mapper will try to map CN into a login and use it.

Configuration entry is as follow:

  # Common Name (CN) to login mapper
  mapper cn {
        debug = false;
	module = internal;
        # module = /usr/lib/pam_pkcs11/cn_mapper.so;
	# mapfile = "file:///etc/pam_pkcs11/cn_mapfile;
	ignorecase = false;
	mapfile = "none"
  }

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.4.2. Subject mapper

Extract Certificate Subject and assume it as login.

  • When used as finder, returns mapped login, or assume login=subject if no map found or provided
  • When used as matcher, try to match provided login, with result obtained by previous find operation

In either case, if a mapfile is used, the mapper will try to map subject into a login and use it.

Configuration file is like:

 # Certificate Subject to login mapper
  mapper file {
        debug = false;
	module = internal;
        # module = /usr/lib/pam_pkcs11/subject_mapper.so;
	ignorecase = true;
	# mapfile = file:///etc/pam_pkcs11/subject_map;
        mapfile = "none";
  }

The mapping file must follow this structure:

....
Certificate Subject -> login
....

Note that some certificates handle strange char mappings (non utf-8) so you must ensure correct byte-to-byte match. You can use provided pkcs11_inspect tool to get and store correct data from certificate

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.4.3. Getpwent() CN to login mapper

Compare CN against getpwent() library call login or gecos returned values to match user login

  • When used as finder use getpwent() system call to retrieve every users on the system. If pw_name or pw_gecos fields match with CN, pw_name is returned as login name
  • When used as matcher, maps CN to an user with via the finder and matches result with login name provided by PAM, returning the result (match or no)

Note: newer implementations of getpwent() libraries, use an additional Name Service Swicth (NSS) infrastructure, that allows administrators to specify how to obtain requested data. This means you can setup /etc/nsswitch.conf password entries to lookup in to /etc/passwd, or LDAP/Kerberos/NIS+/YP services

pw_mapper configuration file shows like:

  mapper pw {
        debug = true;
        ignorecase = false;
	module = internal;
        # module = /usr/lib/pam_pkcs11/pw_mapper.so;
  }

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.4.4. LDAP (lightweight directory access protocol) mapper

Uses an LDAP server to retrieve user name. An additional file tells module the mapping between Cert fields and LDAP entries.

This mapper is still under development.

ldap_mapper configuration file shows like:

  # Directory ( ldap style ) mapper
  mapper ldap {
        debug = false;
        module = /usr/lib/pam_pkcs11/ldap_mapper.so;
        ldaphost = "";
        ldapport = ;
        URI = "";
        scope = 2;
        binddn = "cn=pam,o=example,c=com";
        passwd = "";
        base = "ou=People,o=example,c=com";
        attribute = "userCertificate";
        filter = "(&(objectClass=posixAccount)(uid=%s))"
        # SSL/TLS-Settings
        ssl = tls
        # tls_randfile = ...
        tls_cacertfile = /etc/ssl/cacert.pem
        # tls_cacertdir = ...
        tls_checkpeer = 0
        #tls_ciphers = ...
        #tls_cert = ...
        #tls_key = ...
  }

The following options are recognized by

ldaphost
The FQDN (hostname) oder IP-address of the ldap server.
URI
A space separated list of LDAP URIs. The URIs are used in the given order. If a ldaphost is also submitted, it will be appended to the URI list.
ldapport
The LDAP Port on the server (default: 389 for LDAP and LDAP-TLS and 636 for SSL)
scope
Scope of search: 0-2
  • 0 "base", search only the basedn
  • 1 "one", only the set of records one level below the basedn is searched (default)
  • 2 "sub" means the union of entries at the "base" level and all levels below are searched
binddn
The bind-DN if needed.
passwd
Password for bind-DN
base
The DN of the searchbase (see scope)
attribute
The user attribute in LDAP entry, which contains the certificate. This can be an multi-value attribute. That implies you can store more than one certificate under this attribute. All certificates are utilized.
filter
LDAP filter string. You can use ist to restrict the entries returned by the LDAP server, e.g. by checking other attributes of the user entry. %s is substituted by the user name. (&(objectClass=posixAccount)(uid=%s)) means, only that LDAP entry is returned which has an objectClass "posixAccount" and the uid with the user name. IMPORTANT NOTE: The filter string must be choosen in such a way that only one entry for the user is returned. If an user has more certifactes than these should be collected under the attribute.
ssl
Enable or disable the usage of TLS or SSL
  • off TLS/SSL off(default)
  • tls enable TLS
  • on|ssl enable SSL
tls_randfile
Specifies the path to an entropy source.
tls_cacertfile
Specifies the path to the X.509 certificate for peer authentication.
tls_cacertdir
Specifies the directory containing X.509 certificates for peer authentication.
tls_checkpeer
Specifies whether to require and verify the server certificate or not. 1 check the certificate 0 off (default)
tls_ciphers
Specifies the ciphers to use.
tls_cert
Specifies the path to the file containing the local certificate for client TLS authentication if required.
tls_key
Specifies the path to the file containing the private key for client TLS authentication.

12.4.5. OpenSC library mapper

Search certificate in ${HOME}/.eid/autorized_certificates in a similar way as OpenSC does. When used as login finder, returns the user that owns ${HOME} directory where certificate is found.

This mapper is still under development.

12.4.6. OpenSSH library mapper

Search certificate public key in ${HOME}/.ssh/authorized_keys in a similar way as OpenSSH does. The openssh mapper uses Naming Service Switch (NSS) via getpwent() to get the list of users and home directories

When used as login finder, returns the user that owns the authorized_keys file where the public key is found. If several users share the same public key, returns first found login. On no public key match returns NULL

When used as matcher, the module uses getpwnam() to evaluate user home directory, then tries to open ${HOME}/.ssh/authorized_keys file and finally tries to find a public key that matches with public keys found in certificate. Returns ok if match found, or fail on no match ( or process error )

Configuration file entry looks like:

  mapper openssh {
        debug = false;
        module = /usr/lib/pam_pkcs11/openssh_mapper.so;
  }

NOTE: This mapper is still under development.

12.4.7. Email Cert to login mapper

Email mapper tries to extract an e-mail from certificate. If found does following procedures:

  • if mapfile option is set and file is provided, the module tries to map email field from the certificate to a user (or an alternate email).
  • if mapfile is not set, just use email address from certificate to perform find/match

Once we have a mapped user, module does:

  • When used as finder, just return email or mapped email/user (see above)
  • When used as matcher, compare found email/user against provided by PAM.

Additionally you can set ignorecase or ignoredomain flags:

Domain check (if set) is done by testing if provided email domain part (@ie.this.domain) matches host domain.

E.g. user@my.company.com email in host host.in.my.company.com host matches domain.

Configuration file entry looks like:

  mapper mail {
        debug = false;
	module = internal;
        # module = /usr/lib/pam_pkcs11/mail_mapper.so;
        # MapFile to use
        mapfile = file:///etc/pam_pkcs11/mail_mapping;
        # Some certs store email in uppercase. Take care on this
        ignorecase = true;
        # Also check that host matches mx domain
        ignoredomain = false;
  }

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.4.8. Microsoft Universal Principal Name mapper

Try to find and use Microsoft Universal Principal Name (UPN) extension to evaluate login name.

Microsoft Universal Principal Name is a ASN1-encoded UTF8 string with the syntax login@ADS_Domain. When an UPN is found, the mapper extracts login part as login user. Then, if ignoredomain is unset, try to match domain.

  • When used as finder, returns UPN login as login name (or NULL on fail)
  • When used as matcher compares UPN login against PAM provided login

Configuration file entry looks like:

  mapper ms {
        debug = false;
	module = internal;
        # module = /usr/lib/pam_pkcs11/ms_mapper.so;
        ignorecase = false;
        ignoredomain = false;
	domainname = "domain.com";
  }

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.4.9. Kerberos mapper

Try to find and use Kerberos Principal Name as login name. if mapfile is specified, maps KPN into a login.

NOTES:

  • Kerberos V5 Principal name syntax is assumed: component/component@realm. It's supposed to be stored in ASN1String format in the certificate
  • This mapper does not perform PKINIT Kerberos authentication, just retrieve and use KPN to map login name. (PKINIT auth is still a work in progress)

Configuration entry:

  mapper krb {
        debug = false;
	module = internal;
        # module = /usr/lib/pam_pkcs11/krb_mapper.so;
	ignorecase = false;
	mapfile = "none";
  }

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.4.10.  Unique ID to login mapper

Use Unique ID (UID) field as login name.

Similar to CN mapper, but using UID as field to find/match.

Configuration entry:

  mapper uid {
        debug = false;
	module = internal;
        # module = /usr/lib/pam_pkcs11/uid_mapper.so;
	ignorecase = false;
	mapfile = "none";
  }

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.4.11.  Certificate Digest to login mapper

Evaluates a certificate digest, and try to map result into a login by using a mapfile.

Configuration file should provide the digest algorithm. Depending on OpenSSL configuration all of listed bellow may or not be present in your system.

Configuration entry:

  mapper digest {
        debug = false;
	module = internal;
        # module = /usr/lib/pam_pkcs11/digest_mapper.so;
	# Algorithm used to evaluate certificate digest
        # Select one of:
        # "null","md2","md4","md5","sha","sha1","dss","dss1","ripemd160"
        algorithm = "sha1";
        mapfile = file:///etc/pam_pkcs11/digest_map;
  }

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.4.12. Generic mapper

This mapper groups several mappers in one. You can select which certificate content should be used to deduce/match login, optionally perform a file mapping, and, if desired consult mapped string to NSS services to get final user login.

Three arguments are needed:

  • The certificate field to be used. Allowed values are:
    • "cn" To use Certificate CommonName
    • "subject" To use Certificate Subject
    • "kpn" To use Kerberos PrincipalName
    • "email" To use Certificate Email
    • "upn" To use Microsoft Universal Principal Name
    • "uid" To use Certificate UniqueID
  • A map file name or "none" if no mapping is desired
  • A "use_getpwent" flag, to decide if NSS services are required

Note that fields are taken literally: i.e. no post-processing is done, just take string "as is", and pass it to next step. So if you need some data processing (i.e. use ADS name field in upn) this mapper is not for you.

The first step is extract string from certificate. If a mapping file is required, the string is mapped against mapfile, obtaining a new string. If use_pwent is also required, the mapper compare last one against pw_login or pw_gecos. If a match is done, the pw_login is returned as user login.

When module is user as login finder, returns result of above operations. When user as login matcher, compares provided login with above result.

generic_mapper configuration file shows like:

  mapper generic {
        debug = true;
	module = internal;
        # module = /usr/lib/pam_pkcs11/generic_mapper.so;
	# ignore letter case on match/compare
        ignorecase = false;
	# Use one of "cn" , "subject" , "kpn" , "email" , "upn" or "uid"
	cert_item  = cn;
	# Declare mapfile if needed, else select "none"
	mapfile = file:///etc/pam_pkcs11/generic_mapfile
	# Decide if use getpwent() to map login
	use_getpwent = false;
  }

Note:

As for every other mappers, pklogin_finder tool, doesn't perform the entire process, just returns certificate contents.

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.4.13. Null mapper

Blind access/deny mapper.

If default_match is set to true:

  • When used as finder always returns configuration provided default_user (default: "nobody")
  • When used as matcher always returns OK

If default_match is set to false:

  • When used as finder always returns NULL
  • When used as matcher always returns FAIL

Configuration entry:

  mapper null {
        debug = false;
	module = internal;
        # module = /usr/lib/pam_pkcs11/null_mapper.so;
        # select behaviour: always match, or always fail
        default_match = false;
	# on match, select returned user
	default_user = nobody;
  }

NOTE: This mapper should be the last one in the mapper chain, as it always return valid -- although meaningless -- data

Starting pam-pkcs11-0.5.3 this module is now statically linked, so no need to provide library pathname

12.5. Adding new mappers

Creating new mappers is easy: just retrieve and study the PAM-PKCS#11 Mapper API reference Manual

You'll find sample code, compiling instructions, and a complete list of provided library calls

Chapter 13. Wish list

  1. Make all mappers to use an unified library
  2. Only ask for PIN only when needed (to extract private key for signature verification or pkinit challenge process)
  3. Check that certificate is valid for authentication instead of using first found cert
  4. Finish coding all mappers (OpenSSH, OpenSSL, LDAP to be done)
  5. Implement pkinit to talk Kerberos server
  6. Debug. I cannot test all cases
  7. Lots of docs and samples needs to be written
  8. Check data types on same certificate contents instead of assume utf8or asn1string
  9. Define and document a mapper API. Create pam_pkcs11-devel package

Chapter 14. Contact

Any comments, suggestions and bug reports are welcome. Please, mention the keywords 'pkcs' and 'pam' in the subject.

Juan Antonio Martinez

Mario Strasser