4/7/2022

Openssl Pkcs11 Engine Slot

[UPDATED 2020.06.29]

OpenSSL-based PKCS#11 enginepkcs11 tries to fit the PKCS#11 API within the engine API of OpenSSL. It provides a gateway between PKCS#11 modules and the OpenSSL engine API. One has to register the engine with OpenSSL and one has to provide the path to the PKCS#11 module which should be gatewayed to. Jun 20, 2016 The openssl engine for pkcs#11 by OpenSC is needed to make interaction between openssl and smartcard by pkcs#11 possible. Pkcs11-helper (Which I have never used) is another library to make using PKCS#11 'easier' to use. Pysmime includes basic functions to sign, verify, encrypt and decrypt files or mail messagges in PEM ASCII. The PKCS#11 is a C/C programming standard library for using a cryptographic hardware token with public-key technology. A quick e-mail to the author of the OpenSSL engine component, Geoff Thorpe, confirmed that it would be possible to use a PKCS#11 library with the way the engine was designed.

I already covered how baffling smart cards hardware and standards can be:

But now that you - and presumably I - are no longer in a state of utterhelplessness when confronted by smart cards mumbo jumbo, let’s see whatclever things we can do with them. Coming to mind:

  • Two-factor authentication: PAM, Kerberos, SSH, VPN, web, etc.

  • E-mail: signature and encryption

Now, each of those buzzwords may be familiar to the Linux layman. But - oh dear! -what intricacies, pitfalls, frustrations and sense of despair they entice whensmart cards come into play!

Here be dragons!

Some background

For the sake of the examples below, we’ll assume the following:

  • a PKI smart card from Aventra (MyEID 4.0.0)

  • used with two PIN codes

  • one for each purpose: login (authentication) and e-mail

  • along a card reader from HID Global (Omnikey 3x21 or 5422)

And for the sake of completeness, we’ll use:

  • a smart card-generated login keypair
    (you loose your card, you’re out, you dumbass!)

  • an externally-generated (and backed-up!) e-mail keypair(better still be able to decrypt those e-mails, though, huh?!)

Software versions

Although all necessary packages are readily available in Debian/Stretch, ourchosen use case and hardware requires that we use packages from Debian/Buster:

  • for the Aventra MyEID (4.0.0) smart card (using multiple PINs):
    opensc>= 0.18.0

  • for the HID Omnikey 5422 card reader:
    libccid>= 1.4.27

PKCS#15

The first step is to initalize the smart card and create the necessary PKCS#15structure, along the PIN codes - aka. tokens/slots - for our declared purposes.

  • Install the required Debian packages:

  • PKCS#15 initialization:

  • PINs/PUKs (tokens/slots) creation:

Key pairs and (X.509) certificates

Next, we need to generate/import the required PKI material in each token/slot.

  • Login keypair generation:

  • Login certificate import (after having its CSR properly signed; see the OpenSSL section further below):

  • E-mail key/certificate import (externally-generated and exported into aPKCS#12 bundle; see the OpenSSL section further below):

Smart card preparation finalization

Now that we’re done with the smart card itself, we can “finalize” its preparation:

The exact meaning of this step depends on the actual smart card vendor.

  • on the Aventra MyEID, this switches the card from Creation State to OperationalState; PINs creation are then no longer possible and all access conditions areenforced

PKCS#11

Using smart cards for our purposes will in all cases be achieved thanks to thePKCS#11 software API/stack.

  • Install the required Debian packages:

  • Harden the default OpenSC configuration, in /etc/opensc/opensc.conf:

  • And test its functioning:

WARNINGS:

  • Aventra MyEID smart cards are known to raise (PKCS#11) issues with multiple PINs, unless OpenSC >= 0.18 is used(REF)

PKCS#11 URI

Some libraries and utilities may require you to provide so-called PKCS#11 URIas private key or certificate parameters. Those URIs are standardized by theRFC 7512 and look like:

LibNSS (Thunderbird/Firefox/Chromium)

PKCS#11 support is implemented in Mozilla Thunderbird, Firefox and GoogleChromium thanks to the libnss3 Network Security Services (NSS) library:

  • Add OpenSC driver to NSSDB:

NOTE: For Thunderbird and Firefox, you may need to specify the path to your profile instead of the home directory ~/.pki/nssdb location. Look fora pkcs11.txt file, where modutil will actually have added its magic.

WARNING: For Thunderbird, make sure the emailAddress attribute is includedin the certificate DN (as opposed to theRFC 3850, §.3recommendation) or it will complain about not being able to find the certificateat the moment the message is sent (albeit being correctly configured in theAccount Settings >Security section).

OpenSSL

OpenSSL shall be required to generate the Certificate Signing Request (CSR)corresponding to our login key, as well as issuing the CA-signed X.509certificates for both login and email purposes. Generally speaking, thisimplies:

  • Install the required Debian packages:

  • Create the PKCS#11-friendly openssl.conf:

  • Check the engine is properly configured

  • Create a CSR from a smart card private key:

  • Create a self-signed certificate from a smart card private key:

  • CA-signing a certificate, with the CA private key stored on a smart card:

OpenSSL being the horrifying piece of software that it is (at least to my simpleself), I invite you to discover OpenSSL-Easy, my humble and certainly poorattempt at making one’s OpenSSL life easier:

cURL

cURL relies on OpenSSL engine to perform its PKCS#11 magic. Once the engineinstalled (see above), it is just a matter of using the proper PKCS#11 URIsas private key and certificate arguments:

Secure Shell (SSH)

Using the smart card along SSH for RSA-based authentication is straight-forward,except for one BIG gotcha (see the WARNINGS further below).

  • Export the public key to your SSH authorized keys:

  • Login using your smart card:

  • Optionally temporarily storing your key in the SSH agent:

  • And correctly removing it from the SSH agent once done with it:

WARNINGS:

  • When using multiple PINs and until the changes proposed by RedHat/Fedora areintegrated in OpenSSH:Fedora 28: Better smart card support in OpenSSH
    One MUST use OpenSC’s onepin-opensc-pkcs11.so library to prevent the SSHagent from attempting to unlock all tokens/slots with the same PIN andeventually locking those tokens/slots that do not match.This is also the reason why one MUST create the login token/slot as thefirst one on the smart card.

MIT Kerberos V

Using public key material instead of passwords for Kerberos authenticationis known as PKINIT:

Setting it up is rather straight-forward, albeit not devoid of gotchas (seethe WARNINGS further below).

  • Install the required Debian packages (on both servers and clients):

  • Generating the required servers certificates implies delving into OpenSSL;once again, one’s life may be easier thanks to OpenSSL-Easy:
    OpenSSL-Easy (Authentication section)

  • Debug the Kerberos-specific ASN.1 Subject Alternative Name (SAN) with:

  • Configure the Kerberos Key Distribution Center (KDC) servers;in /etc/krb5kdc/kdc.conf:

  • Configure the Kerberos clients; in /etc/krb5.conf:

WARNINGS:

  • MIT Kerberos V does not allow to enforce PKINIT; if it fails, it willautomatically revert to password-based authentication

  • If one is willing to enforce smart card-based authentication, one shouldlook into using the PAM PKCS#11 module instead of PKINIT (see section below)

Pluggable Authentication Module (PAM)

Using the smart card for authenticating on a Linux box implies adding the PKCS#11module - pam_pkcs11 - to the PAM stack. Again, nothing particularly complicated,except a few gotchas (see the WARNINGS further below).

  • Install the required Debian packages:

  • Configure the PAM PKCS#11 module; in /etc/pam_pkcs11/pam_pkcs11.conf:

  • Configure the PAM authentication stack, in /etc/pam.d/common-auth:

WARNINGS:

  • If MIT Kerberos V is configured for PKINIT (in /etc/krb5.conf), pam_krb5will attempt PKINIT authentication, when password-based fails, even iftry_pkinit is not specified

  • At the time of writing, PAM PKCS#11 module will segfault if any form ofCRL check is attempted

  • The smart card PIN code will be stored by pam_pkcs11 and used as “password”by subsequent modules (e.g. pam_gnome_keyring); this can lead to akward - ifnot unsecure - results; thus our mandating password (Kerberos/LDAP)authentication once PKCS#11’s succeeded
    (see this as “two+”-factor authentication)

Apache (client) authentication

Using the smart card for (client) authentication on the Apache web server in aLDAP-centric environment is far - very far! - from trivial.

I invite you to read the article dedicated on the subject:

OpenVPN

Naively, one would think that using the smart card with OpenVPN would be assimple as:

  • Recovering the PKCS#11 ID(s) for use by OpenVPN:

  • And adding the relevant PKCS#11 stanza to OpenVPN (client) configuration:

Poor you! Nope! Not that easy! Well… Yes… That easy, provided you takeinto account the following well-(and-longime)-known bugs:

Shortly put, you will just need to:

  • retrieve OpenVPN and PKCS#11 helper source packages

  • apply the patches mentioned in the two above bug reports

  • make sure to disable PKCS#11 helper (multi-)threading

  • build the corresponding new Debian packages

  • and install them

  • … what!?!…

GNU Privacy Guard (GnuPG)

GnuPG is expected to be natively used along ad-hoc OpenPGP cards, totallydifferent beasts from the PKCS#15 and X.509-oriented smart cards we’re nowgrowing accustomed to.

Howevever, GnuPG can be made to work with those, again via the PKCS#11 interfaceand some additional trickery:

Pkcs11
  • Install the required Debian package:

  • Configure the GnuPG Agent, in ~/.gnupg/gpg-agent.conf:

  • Configure the GnuPG PKCS#11 Smart Card Daemon (SCD), in ~/.gnupg/gnupg-pkcs11-scd.conf:

  • Where the <login-hash> and <email-hash> are recovered with:

  • Reload the GnuPG Agent and verify everything is ready:

We can therefrom coerce GnuPG into being more X.509 (and S/MIME) friendly:

  • Import our CA root (and intermediate) certificate(s):

  • Import our smart cards certificates:

  • And associate the corresponding (smart card) private keys:

(TODO: unravel the misteries of using the smart card with gpg itself)

WARNINGS:

  • At the time of writing, all of this will only work with RSA keys!

Python requests library

Python requests is nowadays the most ubiquitouslibrary for doing HTTP(S).

However, PKCS#11 isn’t natively supported and requires leveraging theM2Crypto library to hook the necessarygear work in, by replacing the https://adapter (handler) by theM2HttpsAdapter found in:

Which is as simple as it gets:

Encrypt/Decrypt data

Should you need to encrypt/decrypt data using your SmartCard:

Debugging

If you run into troubles, you can easily debug PKCS#11 interactions thanks toOpenSC’s OPENSC_DEBUG or PKCS11SPY environment variables:

Shortcoming: Probabilistic Signature Scheme (PSS) not supported

Probabilistic Signature Scheme (PSS),now creeps in TLS connections relying on OpenSSL 1.1.1 or above. This mayprevent you to use your credentials on websites that moved on to TLS 1.3 or withOpenVPN (which stubbornly refuses to stick to TLS 1.2 and not use PSS),unless you use:

OpenSC 0.20.0 or above

LibP11 0.4.8 or above (<-> OpenSSL engine)

PKCS#11 Helper patch (forecoming 1.26.0 release <-> OpenVPN)

Openssl Pkcs11 Engine Slot

Smart card?!? Easy!!!

OpenSC comes with a number of tools that can be used to generate keys and store certificates on a CardOS 4.3b smart card, this can then be used in FireFox.
This makes it possible to have a completely open source solution for smart cards, one that is available simply using apt-get install in Ubuntu. Note that opensc in Ubuntu 9.10 is buggy so you need Ubuntu 10.04 or manually installed opensc packages.
You can not use a completely blank CardOS 4.3b card because there is a factory key needed in order to set the state of the card so it can be formatted with cardos-tool.
If you have a card formatted as an 'instant id' card, using PrimeCard for example, you cen reformat the card with cardos-tool.
On to the howto
---------------
Check that card is found and display info:
>>cardos-tool -i
Format:
>cardos-tool -fOpenssl pkcs11 engine
Create pkcs15 (E=erase, C=create pkcs15):
>pkcs15-init -EC
Init pkcs15 (P=store pin, a=auth-id, l=label of key):
>pkcs15-init -P -a 01 -l test01
Now pkcs11-tool list a slot:
>pkcs11-tool -L
Generate keys
>pkcs15-init -G RSA1024 -a 01 -l test01

Openssl Engine

Generate cert request with openssl:
>sudo apt-get install libengine-pkcs11-openssl
>openssl

Openssl Pkcs11 Engine Slots

OpenSSL>engine -t dynamic -pre SO_PATH:/usr/lib/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/lib/opensc-pkcs11.so
OpenSSL>req -engine pkcs11 -new -key id_45 -keyform engine -out req.pem -text -subj '/CN=Open SC'

Openssl Pkcs11


Pkcs11 Windows 10

CSR is stored as req.pem. Get certificate from EJBCA using 'Create Certificate from CSR' in public web and store on card:
>pkcs15-init --store-certificate cert.pem -v -i 45

Openssl Pkcs11 Engine Slot Machine

To use in FireFox you just need to add a 'Security Device' with module path /usr/lib/opensc-pkcs11.so