Authenticate into Ubuntu 12.04 with your DNI-e (Spanish ID)

This howto will explain how to setting up pam-pkcs11 for use the DNI-e (Spanish personal ID) as your auth credential and login into Ubuntu with it.

I will assume that you have setted up your DNI-e. If you are looking for a comprehensive howto about this topic you can find it in the next link:

So here we go.

Installing libpam-pkcs11 library

lipam-pkcs11 is a module and related tools for using X509-based smart cards with PAM (Pluggable Authentication Module). PAM is an extendable “daemon” that handles all the attempts of authentication in Linux-based systems.

sudo apt-get install libpam-pkcs11

Getting information from inside the Spanish ID

So now you can use some of the available tools that comes with libpam-pkcs11 to inspect your DNIe. pkcs11_inspect is one of them. With this command you can inspect all the certificates available in your smart card while connected to your smart card reader.

$ pkcs11_listcerts
DEBUG:pam_config.c:203: Invalid CRL policy: no
DEBUG:pkcs11_listcerts.c:69: loading pkcs #11 module...
DEBUG:pkcs11_lib.c:975: PKCS #11 module = [/usr/lib/]
DEBUG:pkcs11_lib.c:992: module permissions: uid = 0, gid = 0, mode = 755
DEBUG:pkcs11_lib.c:1001: loading module /usr/lib/
DEBUG:pkcs11_lib.c:1047: - description: C3PO LTC31 (21070726) 00 00
DEBUG:pkcs11_lib.c:1048: - manufacturer: OpenSC ( [...]
DEBUG:pkcs11_lib.c:1057:   - label: DNI electrónico (PIN1)
DEBUG:pkcs11_lib.c:1058:   - manufacturer: DGP-FNMT
DEBUG:pkcs11_lib.c:1612: Found 3 certificates in token
Found '3' certificate(s)
Certificate #1:
- Algorithm: rsaEncryption
DEBUG:cert_vfy.c:407: Neither CA nor CRL check requested. CertVrfy() skipped
Certificate #2:
- Algorithm: rsaEncryption
DEBUG:cert_vfy.c:407: Neither CA nor CRL check requested. CertVrfy() skipped
Certificate #3:
- Algorithm: rsaEncryption
DEBUG:pkcs11_listcerts.c:160: Process completed

As you can see there are 3 certificates available inside my ID,

  1. one from Spanish police
  2. one in the line that contains ” AUTENTICACIÓN” that means that is a certificate for authentication purposes
  3. and another one in the line that contains “FIRMA”, that means that is a certificate for signing data

I will use the second one.

Configuring libpam-pkcs11

There are some configuration files inside the libpam-pkcs11 debian package that will help us to get this module to work. So we need to create the configuration folder and copy two of those example files:

sudo mkdir -p /etc/pam_pkcs11/cacerts
cd /etc/pam_pkcs11/
sudo cp /usr/share/doc/libpam-pkcs11/examples/{pam_pkcs11.conf.example.gz,subject_mapping.example} /etc/pam_pkcs11/

After that, I have to make a hack to get all the process work. The usual procedure is place the certificate issuers  CRL’s and CA’s files (“Spanish police”‘ certificate files for DNIe) inside the /etc/pam_pkcs11/cacerts folder and execute

sudo pkcs11_make_hash_link

but  with this procedure the libpam-pkcs11 library WILL NOT WORK.

PKCS11 tries to validate my ID certificate against its issuer, the Spanish police. For whatever reason I can’t get pkcs11 to read the certificate files available at  So for now I will deactivate this check. Take notice that this could be REALLY DANGEROUS and I will investigate further to get this to work.

You must change the file /etc/pam_pkcs11/pam_pkcs11.conf and change the line:

cert_policy = ca,signature;


cert_policy = no;

Mapping ID certificates to users

Reached this point you will be wondering how pkcs11 maps system users to DNIe unique cards. For this pam-pkcs11 has a built in extendable mappers, among them you can use a local file, an LDAP server, a Kerberos server, etc. For now I will explain how to setup the local file-based.

Local file-based mapper uses a local file located at /etc/pam_pkcs11/subject_mapping  with the next format:

DNIE-identifier -> localsystemuser

So we only have to replace these parameters with the real ones.

Lets assume that the local system user is “fran”. Now for getting the DNIe-identifier parameter you can use the pkcs11_listcerts command:

$ pkcs11_listcerts |grep AUTEN

this will have the next output:

PIN for token:
- Subject:   /C=ES/serialNumber=myspanishidnumber/SN=mylastname/GN=myname/CN=mylastname, myname (AUTENTICACI\xC3\x93N)

So the DNIE-identifier is “/C=ES/serialNumber=myspanishidnumber/SN=mylastname/GN=myname/CN=mylastname, myname (AUTENTICACI\xC3\x93N)”
So you must add the next line to the /etc/pam_pkcs11/subject_mapping file:

/C=ES/serialNumber=myspanishidnumber/SN=mylastname/GN=myname/CN=mylastname, myname (AUTENTICACI\xC3\x93N) -> fran

Tell PAM to make use of pkcs11 module

Last step! With pkcs11 already set up you have to configure PAM to make use of the pkcs11 module. For this you only have to add the next line to the /etc/pam.d/common-auth. Take notice that must be first non-comment line in the file as PAM uses the «first rule matched wins»

auth       sufficient
# here are the per-package modules (the "Primary" block)
auth    [success=1 default=ignore] nullok_secure

Ok, all configured so from now you can login into your Ubuntu 12.04 system with your DNIe.

More information about libpam-pkcs11 configuration available at


  • Adri Villa Bermúdez

    tengo que probarlo cuanto antes en mi ubuntu, porque estoy hasta el carallo de tener que entrar en windows para hacer algún trámite…

  • Fran Diéguez

    Works like a charm, trust me Adri!
    Now I can sign LibreOffice documents, sign mails with Thunderbird or use it in Firefox for online operations!

  • Luc Van Rompaey


    I found this page while I was trying to get my Belgian eID card to authenticate under Ubuntu 14.04, after I had run into the exact same problem with the “cert_policy = ca,signature;” setting as you did. Setting “cert_policy = no;” circumvented the problem, but I decided to look a little further into the issue.

    Here is what worked for me:

    First, I list the certificates on the card, with command “pkcs15-tool –list-certificates”.
    There are four certificates on my card:
    – X.509 Certificate [Authentication], with ID=02;
    – X.509 Certificate [Signature], with ID=03;
    – X.509 Certificate [CA], with ID=04;
    – X.509 Certificate [Root], with ID=06.

    Since I’m trying to authenticate, I will have to look at the ‘Authentication’ certificate, i.e., ID=02. I read the certificate off the card with command “pkcs15-tool –read-certificate 02 > 02.pem”. The file ’02.pem’ will be created.

    I then display the contents of this certificate with command “openssl x509 -inform pem -in 02.pem -text”.
    Among other things, the ‘Subject’ value will confirm that this is my authentication certificate (‘Subject: C=BE, CN=My Name (Authentication), SN=My Surname, GN=My Given Name/serialNumber=xxxxxxxxxxx’). It will also show the issuer: ‘Issuer: C=BE, CN=Citizen CA/serialNumber=xxxxxx’).

    Since the issuer value talks about a CA, it seems reasonable to assume that it may refer to the ‘CA’ certificate on the card, i.e., ID=04. I therefore read that certificate off the card: “pkcs15-tool –read-certificate 04 > 04.pem”, to create the ’04.pem’ file.

    Again, I display the contents of the certificate: “openssl x509 -inform pem -in 04.pem -text”. The subject value is as expected: ‘Subject: C=BE, CN=Citizen CA/serialNumber=xxxxxx’ (i.e., the issuer of the authentication certificate, see above). The issuer is: ‘Issuer: C=BE, CN=Belgium Root CA3′.

    The issuer talks about a Root, so it appears to refer to the ‘Root’ certificate on the card, i.e., ID=06. I read that certificate off the card as well: “pkcs15-tool –read-certificate 06 > 06.pem”, creating file ’06.pem’.

    For the contents of the certificate, I run “openssl x509 -inform pem -in 06.pem -text”. This shows the expected subject value: ‘Subject: C=BE, CN=Belgium Root CA3′. And, since this is a root certificate, the issuer is the same: ‘Issuer: C=BE, CN=Belgium Root CA3′.

    I now have the chain of CA certificates involved in the authentication process: ’04.pem’ for the CA, ’06.pem’ for the Root CA. Just for practical reasons, I decide to assign more meaningful names to the certificates:
    “mv 04.pem CitizenCA.pem” and “mv 06.pem BelgiumRootCA3.pem”.

    I copy these two files into the ‘/etc/pam_pkcs11/cacerts’ directory, and then run the ‘pkcs11_make_hash_link’ command as follows: “pkcs11_make_hash_link /etc/pam_pkcs11/cacerts”. This will create two soft links into that directory.

    After this, I set “cert_policy = ca;” and authentication with my eID card is successful.

    The opensc software cannot generate digital signatures through a Belgian eID card, and consequently setting “cert_policy = ca, signature” will not work. That’s because the Private Key on the card cannot be accessed by the outside world (and rightly so!), and you can generate digital signatures only through a GUI (to input the PIN), which is not implemented by the opensc software.