YKCS11

This is a PKCS#11 module that allows external applications to communicate with the PIV application running on a YubiKey.

This module is based on version 2.40 of the PKCS#11 (Cryptoki) specifications. The complete specifications are available at oasis-open.org.

Building

YKCS11 is automatically built as part of yubico-piv-tool and the following command will suffice:

mkdir build; cd build
cmake ..
make
sudo make install

More info about building yubico-piv-tool can be found in the related README file or in yubico-piv-tool.

Once installed, the module will be found by default in /usr/local/lib/libykcs11.so otherwise it will be built locally in yubico-piv-tool/build/ykcs11/libykcs11.so

Portability

The module has been developed and tested using Ubuntu Linux, MacOS and Windows. Both MacOS and Windows use PCSC as a backend.

YKCS11 on Windows

After installing yubico-piv-tool using the windows installer, the Yubico PIV Tool\bin directory needs to be added to the system path in order for other applications to be able to load it. This is because the libykcs11.dll is dynamically linked to libykpiv.dll and to libcrypto-1_1.dll and both of them need to be accessible for ykcs11 to be useful.

On Windows 10, setting the system path is done by following these steps:

1- Go to Control Panel → System and Security → System → Advanced system setting

2- Click “Environment Variables…“

3- Under System Variables, highlight “Path“ and click “Edit…“

4- Click “New“ and add the absolute path to yubico-piv-tool/bin

If setting the system path is not desirable, the libykpiv.dll and libcrypto-1_1.dll can be copied into the same directory as the application that needs to access the ykcs11 module.

A Note for Developers

If LoadLibrary is called with an absolute path, it will not look for dependencies of the specified DLL in that directory, but rather in the startup directory of the application that calls LoadLibrary. The solution is to either:

  • Call LoadLibraryEx with the flag LOAD_WITH_ALTERED_SEARCH_PATH for absolute paths

  • Add the directory where ykcs11 is located to the system PATH

  • Or copy the dependencies into the application directory.

Please note that calling LoadLibraryEx with that flag for a non-absolute path is undefined behavior according to MS docs. For example, the way Pkcs11Interop does it is to set a variable to LOAD_WITH_ALTERED_SEARCH_PATH if the path looks absolute, and 0 otherwise; and then always calling LoadLibraryEx. If the flags is 0 then LoadLibraryEx behaves exactly like LoadLibrary.

Key Mapping

The module provides access to all 25 keys that can be stored on the YubiKey PIV application. These keys correspond to the keys in the PIV slots as described in PIV Certificate Slots and are accessible through yubico-piv-tool.

The mapping is as follows:

ykcs11 id PIV

1

9a

2

9c

3

9d

4

9e

5 - 24

82 - 95

25

f9

Key Generation

Key pair generation is a particular operation, in the sense that within PIV this is the only moment where the newly created public key is given back to the user. To prevent the key from being lost, it is automatically stored within the YubiKey by wrapping it in an X.509 certificate.

Attestation Certificates

Attestation certificates are also accessible with the YKCS11 module. An attestation certificate is a regular X509 Certificates that has the same CKA_ID and public key as the key it is attesting. Attestation certificates, however, are not stored in the YubiKey (CKA_TOKEN is FALSE) and are generated when accessed.

For more details about attestation, see the Attestation section.

User Types

YKCS11 defines two types of users: a regular user and a security officer (SO). These have been mapped to perform regular usage of the private key material (PIN-associated operations) and device management (management-key associated operations).

PINs and Management Key

The default user PIN for the YubiKey is 123456.
The default management key is 010203040506070801020304050607080102030405060708.
All the YubiKey personalization (e.g. changing management key, resetting PINs, resetting the application) is currently done using yubico-piv-tool.

In order to perform operations involving the private keys, a regular user must be logged in (i.e. using the PIN). However, given the different PIN policies for different keys, subsequent operations might require a new login. This is supported by the module through the CONTEXT_SPECIFIC user in accordance with the specifications.

OpenSSL

The YubiKey only supports functions that require an asymmetrinc private key. Functions that do not, like encryption, signature verification, hashing and generation of a random number, are done by OpenSSL.

Also, the YubiKey only performs raw decryption and signature. So when padding is used, for example OAEP and PSS padding, applying and removing the padding is handled using OpenSSL functions.

Testing

Apart from the internal tests, the YKCS11 has also been tested with the Pkcs11Interop .NET library

Debugging

By default, the module has debugging disabled. This is highly verbose and might be confusing.

To enable debugging of the ykcs11 module, the variable YKCS11_DBG needs to be set to a numerical value 1 to 9 (the value 0 indicates disabled debugging). YKCS11_DBG can be set in one of the following ways:

  1. Set the environment variable YKCS11_DBG

  2. Rebuild the project as follows (2 here is an example):

    mkdir build; cd build
    cmake .. -DYKCS11_DBG=2
    make
    sudo make install
    

It is also possible to use PKCS#11 Spy, as provided by OpenSC, to inspect the PKCS#11 communication.