.. piv-tool-ykcs11.rst .. _piv-tool-ykcs11: =================== PIV YKCS11 Module =================== Yubico ``YKCS11`` 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 > `PKCS #11 Cryptographic Token Interface Base Specification Version 2.40 `_. Building ========= YKCS11 is automatically built as part of ``yubico-piv-tool``. For example: .. code-block:: $ mkdir build; cd build $ cmake .. $ make $ sudo make install For additional information about building ``yubico-piv-tool``, :ref:`piv-setup`. After the yuvico-piv-tool is installed, the default location for the ykcs11 module is: ``/usr/local/lib/libykcs11.so``. Optionally, you can be built it 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, add the ``Yubico PIV Tool\bin`` directory to the system path, so other applications can load it. This is also recommended, because the ``libykcs11.dll`` is dynamically linked to ``libykpiv.dll`` and ``libcrypto-1_1.dll``, and setting the system path enables ``ykcs11`` to access both of them. On Windows 10, to set the system path: 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``. Alternatively, if you do not want to set the system path, copy ``libykpiv.dll`` and ``libcrypto-1_1.dll`` 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 does **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. * Copy the dependencies into the application directory. .. Note:: Calling ``LoadLibraryEx`` with the ``LOAD_WITH_ALTERED_SEARCH_PATH`` flag for a non-absolute path is undefined behavior according to MicroSoft documentation. For example, Pkcs11Interop sets a variable to ``LOAD_WITH_ALTERED_SEARCH_PATH`` if the path looks absolute, and ``0`` otherwise. After that, it always calls ``LoadLibraryEx``. This means, if the flag is ``0`` then ``LoadLibraryEx`` behaves exactly like ``LoadLibrary``. Key Mapping ============ The ``ykcs11`` 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: .. table:: +----------------------+---------------------+ | 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 :ref:`piv-tool-attestation` and ``Action``, :ref:`attest`. User Types =========== YKCS11 defines two types of users: a regular user and a security officer (SO). These are mapped to perform regular tasks for 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``. To perform operations involving the private keys, a regular user must be logged in (using the PIN or fingerprint). 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. Keys with PIN policy "never" ============================= It is possible to skip PIN verification when using keys with PIN policy "never" by using ``VERIFY_NONE`` as a PIN. Fingerprint Authentication with YubiKey Bio ============================================ It is also possible to use the fingerprint reader on the YubiKey Bio to login. Attempting to login with an empty PIN triggers a bio verification. The user is then expected to scan their fingerprint. Note: there might not be an indication on the screen that a fingerprint scan is expected, but the YubiKey blinks while it waits for a fingerprint scan. Bio verification can also be triggered by using ``VERIFY_BIO`` as a PIN. OpenSSL ======= The YubiKey only supports functions that require an asymmetric private key. Functions that do not, like encryption, signature verification, hashing and generation of a random number, are done by OpenSSL. Additionally, the YubiKey only performs raw decryption and signature. 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 ykcs11 module has debugging disabled. Debugging is *highly* verbose and might be confusing. To enable debugging of the ykcs11 module, set the variable ``YKCS11_DBG`` to a numerical value ``1`` to ``9``. The value ``0`` indicates disabled debugging. Set ``YKCS11_DBG`` for debugging, using one of the methods: * Set the environment variable ``YKCS11_DBG``. * Rebuild the project as follows. The value ``2`` here is an example: .. code-block:: $ mkdir build; cd build $ cmake .. -DYKCS11_DBG=2 $ make $ sudo make install Alternatively, use `PKCS#11 Spy `_ as provided by OpenSC, to inspect the PKCS#11 communication. .. _piv-tool-ykcs11-objects: YKCS11 Functions and Objects ============================ See the following tables of YKCS11 functions and objects. Supported PKCS#11 Functions ---------------------------- .. table:: :class: longtable +--------------------+---------------------------------+----------------------+ | PKCS#11 Function | Mechanism | Comment | +====================+=================================+======================+ | C_Initialize | | | +--------------------+---------------------------------+----------------------+ | C_Finalize | | | +--------------------+---------------------------------+----------------------+ | C_GetInfo | | | +--------------------+---------------------------------+----------------------+ | C_GetFunctionList | | | +--------------------+---------------------------------+----------------------+ | C_GetSlotList | | | +--------------------+---------------------------------+----------------------+ | C_GetSlotInfo | | | +--------------------+---------------------------------+----------------------+ | C_GetTokenInfo | | | +--------------------+---------------------------------+----------------------+ | C_GetMechanismList | | | +--------------------+---------------------------------+----------------------+ | C_GetMechanismInfo | | | +--------------------+---------------------------------+----------------------+ | C_InitToken | | | +--------------------+---------------------------------+----------------------+ | C_SetPIN | | | +--------------------+---------------------------------+----------------------+ | C_OpenSession | | | +--------------------+---------------------------------+----------------------+ | C_CloseSession | | | +--------------------+---------------------------------+----------------------+ | C_CloseAllSessions | | | +--------------------+---------------------------------+----------------------+ | C_GetSessionInfo | | | +--------------------+---------------------------------+----------------------+ | C_Login | | | +--------------------+---------------------------------+----------------------+ | C_Logout | | | +--------------------+---------------------------------+----------------------+ | C_CreateObject | || With CKO_PRIVATE_KEY| | | || or CKO_CERTIFICATE | +--------------------+---------------------------------+----------------------+ | C_DestroyObject | | | +--------------------+---------------------------------+----------------------+ | C_GetObjectSize | | | +--------------------+---------------------------------+----------------------+ | C_GetAttributeValue| | | +--------------------+---------------------------------+----------------------+ | C_FindObjectsInit | | | +--------------------+---------------------------------+----------------------+ | C_FindObjects | | | +--------------------+---------------------------------+----------------------+ | C_FindObjectsFinal | | | +--------------------+---------------------------------+----------------------+ | C_EncryptInit || CKM_RSA_X_509, || With RSA keys only. | | || CKM_RSA_PKCS, || Uses OpenSSL | | || CKM_RSA_PKCS_OAEP || encryption functions| +--------------------+---------------------------------+----------------------+ | C_Encrypt | || With RSA keys only. | | | || Uses OpenSSL | | | || encryption functions| +--------------------+---------------------------------+----------------------+ | C_EncryptUpdate | || With RSA keys only. | | | || Uses OpenSSL | | | || encryption functions| +--------------------+---------------------------------+----------------------+ | C_EncryptFinal | || With RSA keys only. | | | || Uses OpenSSL | | | || encryption functions| +--------------------+---------------------------------+----------------------+ | C_DecryptInit || CKM_RSA_X_509, | With RSA keys only. | | || CKM_RSA_PKCS, | | | || CKM_RSA_PKCS_OAEP | | +--------------------+---------------------------------+----------------------+ | C_Decrypt | | With RSA keys only. | +--------------------+---------------------------------+----------------------+ | C_DecryptUpdate | | With RSA keys only. | +--------------------+---------------------------------+----------------------+ | C_DecryptFinal | | With RSA keys only. | +--------------------+---------------------------------+----------------------+ | C_DigestInit || CKM_SHA_1, CKM_SHA256, || Uses OpenSSL digest | | || CKM_SHA384, CKM_SHA512 || functions | +--------------------+---------------------------------+----------------------+ | C_Digest | || Uses OpenSSL digest | | | || functions | +--------------------+---------------------------------+----------------------+ | C_DigestUpdate | || Uses OpenSSL digest | | | || functions | +--------------------+---------------------------------+----------------------+ | C_DigestFinal | || Uses OpenSSL digest | | | || functions | +--------------------+---------------------------------+----------------------+ | C_SignInit || CKM_RSA_X_509, | | | || CKM_RSA_PKCS, | | | || CKM_SHA1_RSA_PKCS, | | | || CKM_SHA256_RSA_PKCS, | | | || CKM_SHA384_RSA_PKCS, | | | || CKM_SHA512_RSA_PKCS, | | | || CKM_RSA_PKCS_PSS, | | | || CKM_SHA1_RSA_PKCS_PSS, | | | || CKM_SHA256_RSA_PKCS_PSS, | | | || CKM_SHA384_RSA_PKCS_PSS, | | | || CKM_SHA512_RSA_PKCS_PSS, | | | || CKM_ECDSA, | | | || CKM_ECDSA_SHA1, | | | || CKM_ECDSA_SHA224, | | | || CKM_ECDSA_SHA256, | | | || CKM_ECDSA_SHA384 | | | || CKM_EDDSA | | +--------------------+---------------------------------+----------------------+ | C_Sign | | | +--------------------+---------------------------------+----------------------+ | C_SignUpdate | | | +--------------------+---------------------------------+----------------------+ | C_SignFinal | | | +--------------------+---------------------------------+----------------------+ | C_VerifyInit || CKM_RSA_X_509, || Uses OpenSSL | | || CKM_RSA_PKCS, || verification | | || CKM_SHA1_RSA_PKCS, || functions | | || CKM_SHA256_RSA_PKCS, | | | || CKM_SHA384_RSA_PKCS, | | | || CKM_SHA512_RSA_PKCS, | | | || CKM_RSA_PKCS_PSS, | | | || CKM_SHA1_RSA_PKCS_PSS, | | | || CKM_SHA256_RSA_PKCS_PSS, | | | || CKM_SHA384_RSA_PKCS_PSS, | | | || CKM_SHA512_RSA_PKCS_PSS, | | | || CKM_ECDSA, | | | || CKM_ECDSA_SHA1, | | | || CKM_ECDSA_SHA224, | | | || CKM_ECDSA_SHA256, | | | || CKM_ECDSA_SHA384 | | | || CKM_EDDSA | | +--------------------+---------------------------------+----------------------+ | C_Verify | || Uses OpenSSL | | | || verification | | | || functions | +--------------------+---------------------------------+----------------------+ | C_VerifyUpdate | || Uses OpenSSL | | | || verification | | | || functions | +--------------------+---------------------------------+----------------------+ | C_VerifyFinal | || Uses OpenSSL | | | || verification | | | || functions | +--------------------+---------------------------------+----------------------+ | C_GenerateKeyPair || CKM_RSA_PKCS_KEY_PAIR_GEN, | | | || CKM_EC_KEY_PAIR_GEN | | | || CKM_EC_EDWARDS_KEY_PAIR_GEN | | | || CKM_EC_MONTGOMERY_KEY_PAIR_GEN | | +--------------------+---------------------------------+----------------------+ Supported PKCS#11 Objects -------------------------- Not all PKCS#11 Object types are implemented. This is a list of what is implemented and what it maps to. .. table:: +-------------------+--------------------+-------------------------------------+ | PKCS#11 | Supported CKK | Comment | +===================+====================+=====================================+ | CKO_PRIVATE_KEY || CKK_RSA, || YubiKey 5.7 or later required for: | | || CKK_EC, || RSA 1024, 2048, 3072, | | || CKK_ED_EDWARDS, || RSA 4096 with e=0x10001, | | || CKK_EC_MONTGOMERY || EC with secp256r1 and secp384r1, | | || || ED2559, and X25519 | +-------------------+--------------------+-------------------------------------+ | CKO_PUBLIC_KEY | || Stored in X509 Certificates | +-------------------+--------------------+-------------------------------------+ | CKO_CERTIFICATE | || X509 Certificates containing | | | || either the public key or the | | | || attestation certificate | +-------------------+--------------------+-------------------------------------+ | CKO_DATA | | | +-------------------+--------------------+-------------------------------------+ Supported Attributes per Object Type ------------------------------------- .. table:: :class: longtable +-------------------------+-------------+-------------+--------------+---------+ || Attribute || Private || Public || Certificate || Data | || || key object || key object || object || object | +=========================+=============+=============+==============+=========+ | CKA_CLASS | X | X | X | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_ID | X | X | X | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_TOKEN | X | X | X | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_PRIVATE | X | X | X | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_LABEL | X | X | X | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_APPLICATION | | | | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_OBJECT_ID | | | | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_MODIFIABLE | X | X | X | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_COPYABLE | X | X | X | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_DESTROYABLE | X | X | X | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_VALUE | | | X | X | +-------------------------+-------------+-------------+--------------+---------+ | CKA_SUBJECT | | | X | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_ISSUER | | | X | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_SERIALNUMBER | | | X | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_CERTIFICATE_TYPE | | | X | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_TRUSTED | | X | X | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_KEY_TYPE | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_SENSITIVE | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_ALWAYS_SENSITIVE | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_EXTRACTABLE | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_NEVER_EXTRACTABLE | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_LOCAL | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_ENCRYPT | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_DECRYPT | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_WRAP | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_WRAP_WITH_TRUSTED | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_UNWRAP | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_SIGN | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_SIGN_RECOVER | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_VERIFY | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_VERIFY_RECOVER | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_DERIVE | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_MODULUS | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_EC_POINT | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_EC_PARAMS | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_MODULUS_BITS | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_PUBLIC_EXPONENT | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ | CKA_ALWAYS_AUTHENTICATE | X | X | | | +-------------------------+-------------+-------------+--------------+---------+ Key Alias per Slot and Object Type ----------------------------------- Some applications, mainly Java, specify the keys to use by their key alias, which is referred to as a key's label by PKCS#11. Objects' labels as access by YKCS11 are fixed values and are unmodifiable. Following is the list of object labels according to their object type and the slot they reside in (See `PIV Certificate Slots `_ for the slot usage). .. table:: :class: longtable +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ || Slot || Private key || Public key || Certificate || Attestation || Data | || || || || || certificate || object | +=======+=================+=================+=================+=================+=================+ | 9a || Private key || Public key || X.509 || X.509 || X.509 | | || for PIV || for PIV || Certificate || Certificate || Certificate | | || Authentication || Authentication || for PIV || for PIV || for PIV | | || || || Authentication || Attestation 9a || Authentication | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 9c || Private key || Public key || X.509 || X.509 || X.509 | | || for Digital || for Digital || Certificate || Certificate || Certificate | | || Signature || Signature || for Digital || for PIV || for Digital | | || || || Signature || Attestation 9c || Signature | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 9d || Private key || Public key || X.509 || X.509 || X.509 | | || for Key || for Key || Certificate || Certificate || Certificate | | || Management || Management || for Key || for PIV || for Key | | || || || Management || Attestation 9d || Management | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 9e || Private key || Public key || X.509 || X.509 || X.509 | | || for Card || for Card || Certificate || Certificate || Certificate | | || Authentication || Authentication || for Card || for PIV || for Card | | || || || Authentication || Attestation 9a || Authentication | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 82 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 1 || Key 1 || for Retired || for PIV || for Retired | | || || || Key 1 || Attestation 82 || Key 1 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 83 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 2 || Key 2 || for Retired || for PIV || for Retired | | || || || Key 2 || Attestation 83 || Key 2 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 84 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 3 || Key 3 || for Retired || for PIV || for Retired | | || || || Key 3 || Attestation 84 || Key 3 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 85 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 4 || Key 4 || for Retired || for PIV || for Retired | | || || || Key 4 || Attestation 85 || Key 4 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 86 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 5 || Key 5 || for Retired || for PIV || for Retired | | || || || Key 5 || Attestation 86 || Key 5 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 87 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 6 || Key 6 || for Retired || for PIV || for Retired | | || || || Key 6 || Attestation 87 || Key 6 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 88 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 7 || Key 7 || for Retired || for PIV || for Retired | | || || || Key 7 || Attestation 88 || Key 7 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 89 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 8 || Key 8 || for Retired || for PIV || for Retired | | || || || Key 8 || Attestation 89 || Key 8 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 8a || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 9 || Key 9 || for Retired || for PIV || for Retired | | || || || Key 9 || Attestation 8a || Key 9 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 8b || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 10 || Key 10 || for Retired || for PIV || for Retired | | || || || Key 10 || Attestation 8b || Key 10 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 8c || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 11 || Key 11 || for Retired || for PIV || for Retired | | || || || Key 11 || Attestation 8c || Key 11 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 8d || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 12 || Key 12 || for Retired || for PIV || for Retired | | || || || Key 12 || Attestation 8d || Key 12 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 8e || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 13 || Key 13 || for Retired || for PIV || for Retired | | || || || Key 13 || Attestation 8e || Key 13 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 8f || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 14 || Key 14 || for Retired || for PIV || for Retired | | || || || Key 14 || Attestation 8f || Key 14 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 90 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 15 || Key 15 || for Retired || for PIV || for Retired | | || || || Key 15 || Attestation 90 || Key 15 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 91 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 16 || Key 16 || for Retired || for PIV || for Retired | | || || || Key 16 || Attestation 91 || Key 16 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 92 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 17 || Key 17 || for Retired || for PIV || for Retired | | || || || Key 17 || Attestation 92 || Key 17 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 93 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 18 || Key 18 || for Retired || for PIV || for Retired | | || || || Key 18 || Attestation 93 || Key 18 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 94 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 19 || Key 19 || for Retired || for PIV || for Retired | | || || || Key 19 || Attestation 94 || Key 19 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | 95 || Private key || Public key || X.509 || X.509 || X.509 | | || for Retired || for Retired || Certificate || Certificate || Certificate | | || Key 20 || Key 20 || for Retired || for PIV || for Retired | | || || || Key 20 || Attestation 95 || Key 20 | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ | f9 || Private key || Public key || X.509 || X.509 || X.509 | | || for PIV || for PIV || Certificate || Certificate || Certificate | | || Attestation || Attestation || for PIV || for PIV || for PIV | | || || || Attestation || Attestation f9 || Attestation | +-------+-----------------+-----------------+-----------------+-----------------+-----------------+ .. _piv-tool-ykcs11-apps: YKCS11 Supported Applications ============================== The YKCS11 module was tested with the following applications: * :ref:`piv-ykcs11-firefox-label` * :ref:`piv-ykcs11-fortify-label` * :ref:`piv-ykcs11-java-keytool-label` * :ref:`piv-ykcs11-opensc-pkcs11tool-label` * :ref:`piv-ykcs11-openssh-label` * :ref:`piv-ykcs11-openssl-pkcs11-engine-label` ---------- .. _piv-ykcs11-firefox-label: FireFox -------- With FireFox, it is possible to authenticate to websites and other web services with certificates stored on a smartcard and accessed through a PKCS#11 module. In order to do that, the PKCS#11 module needs to be added to FireFox as a Security Device. However, in order for FireFox to recognize the certificate in the smartcard, it needs to have previously imported its issuer certificate (typically a CA certificate) as a trusted authority. Importing CA Certificate on FireFox ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Open FireFox Certificate Manager. Go to **Preferences → Privacy & Security → View Certificates**. .. figure:: /graphics/firefox-privacy-security.png :align: center :width: 100% *Select Privacy & Security* .. figure:: /graphics/firefox-view-certs-button.png :align: center :width: 100% *View Certificates* 2. Go to **Authorities** and click **Import**. .. figure:: /graphics/firefox-authorities-import.png :align: center :width: 100% *Import Authority* 3. Navigate to the issuer certificate and choose it. Adding YKCS11 Security Device on FireFox ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Open FireFox Device Manager. Go to **Preferences → Privacy & Security → Security Devices**. .. figure:: /graphics/firefox-security-devices.png :align: center :width: 100% *View Security Devices* 2. Click **Load**. .. figure:: /graphics/firefox-load-device.png :align: center :width: 100% *Load Security Devices* 3. Choose a name for the YKCS11 module, navigate to libykcs11.so, and choose it, then click OK. .. figure:: /graphics/firefox-name-module.png :align: center :width: 100% *Security Devices Load Driver* The YKCS11 module should now appear in the Security devices column on the left. .. figure:: /graphics/firefox-verify-added.png :align: center :width: 100% *Device Manager Listing for Yubico Information* Viewing and Downloading a Certificate on FireFox ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. Caution:: If the certificate issuer is not trusted (aka not imported) by FireFox, the certificate details only show an error message. 1. Open FireFox Certificate Manager. Go to **Preferences → Privacy & Security → View Certificates**. 2. Highlight the certificate and click **View**. The certificate details are displayed in a FireFox tab. .. figure:: /graphics/firefox-view-added-certificate.png :align: center :width: 100% *Certificate Manager View* 3. To download the certificate, find the download link in the certificate details tab. It is possible to download only the certificate or the entire certificate chain in PEM format. .. figure:: /graphics/firefox-download-cert.png :align: center :width: 100% *Certificate Information Download* Other Functionality on FireFox ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ With FireFox, it is possible to access and download the certificate. It is also possible to change the PIV user pin with the **Change Password** button in the Certificate Manager. Generally, FireFox has functionality to export the private key (with the **Backup** button in the Certificate Manager). This, however, fails because the YubiKey does not allow the private key to leave it. Deleting a key through FireFox does not work either unless the user is logged in as an SO user. ---------- .. _piv-ykcs11-fortify-label: Fortify -------- Fortify is a locally installed application that listens on a known TCP port and enables web applications to use smart cards, security tokens, and locally installed certificates. Fortify has native support for YubiKey's PIV interface through the YKCS11 module. 1. Go to `fortifyapp.com `_ to download and then install the application specific to your platform. 2. When running the application, a small shield-shaped icon close to the **start menu** should appear. 3. Verify matching codes. a. Click the Fortify icon and go to **Tools**. A browser opens with the Fortify webapp interface. .. figure:: /graphics/fortify-tools.png :align: center :width: 50% *Fortify Tools Menu* b. You are presented with a code inside the webpage and a code outside of it. If the codes match, click **Approve**. .. figure:: /graphics/fortify-code-match.png :align: center :width: 100% *Fortify Interface Verification* 4. View stored YubiKey certificates. In the Fortify web interface: a. Select the Yubico provider. .. figure:: /graphics/fortify-web-ui.png :align: center :width: 50% *Fortify Select Provider* b. At the prompt, enter the PIN of the PIV user. .. figure:: /graphics/fortify-pin-prompt.png :align: center :width: 50% *Fortify PIN* c. In the panel, view the list of certificates stored in the YubiKey. .. figure:: /graphics/fortify-yb-piv-attestation.png :align: center :width: 100% *Fortify View Certificates* Tips for using Fortify ~~~~~~~~~~~~~~~~~~~~~~~ Fortify expects to find the YKCS11 module in the following locations: * MacOS: ``/usr/local/lib/libykcs11.dylib`` * Linux: ``/usr/local/lib/libykcs11.so`` * Windows: ``%WINDIR/System32/libykcs11-1.dll`` The paths are specified in a file called ``card.json``. On a Linux system, this file might reside in ``$HOME/.fortify/card.json``. ---------- .. _piv-ykcs11-java-keytool-label: Java Keytool ------------- The YKCS11 module can be used with Java keytool through the SunPKCS11 provider that is shipped with Java by default. To configure the SunPKCS11 provider to use the YKCS11, create a configuration file, let's call it ``sun_ykcs11.conf``, with the following content: .. code:: name = ykcs11 library = /path/to/libykcs11.so The name is an arbitrary string. This configuration file should then be used as the provider's argument parameter in the command line. List Content ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: $ keytool -list -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /path/to/sun_ykcs11.conf Where -- ``-keystore NONE`` indicates that the keys are not stored in a soft token, aka not a file. ``-storetype PKCS11`` indicates that the keys are accessible through the PKCS#11 interface. Signing a JAR File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To sign a jar file using ``jarsigner``, specify the alias of the signing key. The aliases of the keys stored on the YubiKey PIV are fixed and unmodifiable. To view the list of key aliases: * Use the YubiKey command, ``keytool -list``, shown in Example 1 above. * See :ref:`piv-tool-ykcs11-objects`. Example of signing a jar file with the key on slot 9c: .. code:: $ jarsigner -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /path/to/sun_ykcs11.conf lib.jar "X.509 Certificate for Digital Signature" To display PKCS11 debug messages, add the parameter ``-J-Djava.security.debug=sunpkcs11``: .. code:: $ jarsigner -verify -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /path/to/sun_ykcs11.conf lib.jar "X.509 Certificate for Digital Signature" -J-Djava.security.debug=sunpkcs11\ The jarsigner command returns two files appearing under META-INF inside the jar file. One of them has the ending ``.SF`` and the other has the ending ``.EC`` or ``.RSA`` depending on the key type of the signing key. To verify the signature of a jar file, run: .. code:: $ jarsigner -verify -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg /path/to/sun_ykcs11.conf lib.jar "X.509 Certificate for Digital Signature" ---------- .. _piv-ykcs11-opensc-pkcs11tool-label: OpenSC pkcs11-tool ------------------- The YKCS11 module works well with ``pkcs11-tool``. Be aware though that older versions of OpenSC (like the ones available on Linux distributions) might produce errors when running some commands. If so, try again after installing a newer version. Display Device Info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: $ pkcs11-tool --module /path/to/libykcs11.so --show-info Key Generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Only the SO user is permitted to generate keys. The SO's PIN is the PIV management key. * Generate an EC key in slot 9A using curve ``secp384r1`` .. code:: $ pkcs11-tool --module /path/to/libykcs11.so --login --login-type so --keypairgen --id 1 --key-type EC:secp384r1 * Generate an EC key in slot 9E using curve ``prime256v1`` .. code:: $ pkcs11-tool --module /path/to/libykcs11.so --login --login-type so --keypairgen --id 4 --key-type EC:prime256v1 * Generate an RSA key in slot 9C .. code:: $ pkcs11-tool --module /path/to/libykcs11.so --login --login-type so --keypairgen --id 2 --key-type rsa:2048 Signing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signatures generated using ``pkcs11-tool`` can be verified using, for example, ``openssl``. To verify the signature with ``openssl``, the public key needs to be extracted from the certificate. To do that, complete the steps: 1. Export the certificate from the YubiKey using the YubiKey Manager, ``ykman``, ``yubico-piv-tool``, FireFox or any other available tool. 2. If the certificate is not in ``PEM`` format, convert it into ``PEM`` format. 3. Extract the public key from the certificate. Run the following command: .. code:: $ openssl x509 -in cert.pem -pubkey -noout > pubkey.pem The following are a few command line examples of signing data with ``pkcs11-tool`` and verifying the signature with ``openssl``. * Sign data with an RSA key in slot 9E. .. code:: $ pkcs11-tool --module /path/to/libykcs11.so --sign --id 4 -i data.txt -o data.sig $ openssl rsautl -verify -in data.sig -inkey 9e_pubkey.pem -pubin * Sign data with an RSA key in slot 9C and SHA256. .. code:: $ pkcs11-tool --module /path/to/libykcs11.so --sign -m RSA-SHA256 --id 2 -i data.txt -o data.sig $ openssl dgst -sha256 -verify 9c_pubkey.pem -signature data.sig data.txt * Signing data with an EC key in slot 9A and SHA1. .. code:: $ pkcs11-tool --module /path/to/libykcs11.so --sign --id 1 -m ECDSA-SHA1 --signature-format openssl -i data.txt -o data.sig $ openssl dgst -sha1 -verify 9a_pubkey.pem -signature data.sig data.txt Testing RSA Keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ At least one RSA key needs to already exist in the YubiKey for this test to work. .. code:: $ pkcs11-tool --module /path/to/libykcs11.so --login --test Testing EC Keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ With the default installation of the YubiKey's PIV, testing EC keys works only on slot 9C. This is because ``pkcs11-tool --test-ec`` assumes that the same user can both generate a keypair and sign data. This, however, is not allowed by the YubiKey, which implements separation of duty more strictly. By default, however, the key that resides on slot 9C has its ``CKA_ALWAYS_AUTHENTICATE`` attribute set to True, which prompts the user for the PIN during the different operations, and so the right PIN can be entered at the right time. .. code:: $ pkcs11-tool --module /path/to/libykcs11.so --login --login-type so --test-ec --id 2 --key-type EC:secp256r1 ---------- .. _piv-ykcs11-openssh-label: OpenSSH -------- Keys stored on the YubiKey can be used to login to remote SSH servers. This can be done either with the YubiKey PIV application using, for example, OpenSSH, or with the YubiKey PGP application. Following are some command line examples of using OpenSSH with the Yubikey PIV application through YKCS11. For guides on how to use the YubiKey PGP application with SSH, see `SSH authentication `_. To direct OpenSSH to use keys stored on the YubiKey, specify the YKCS11 module with the ``-I`` option in the command. .. code:: $ ssh -I /path/to/libykcs11.so git@github.com To download the public key accessible through the YKCS11 module: .. code:: $ ssh-keygen -D /path/to/libykcs11.so ---------- .. _piv-ykcs11-openssl-pkcs11-engine-label: OpenSSL via PKCS11 Engine -------------------------- The easiest way to get OpenSSL to work with YKCS11 via ``engine_pkcs11`` is by using the ``pll-kit`` proxy module. To get the OpenSSL PKCS11 engine to use the Yubico YKCS11 module specifically, set the environment variable ``PKCS11_MODULE_PATH`` to point to ``libykcs11.so`` module. For more details on PKCS11 engine, see `OpenSC libp11 `_. For more details on how to configure OpenSSL PKCS11 engine for Yubico supported modules, see `OpenSSL with YubiHSM 2 via engine_pkcs11 and yubihsm_pkcs11 `_. Data Signing with OpenSSl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: $ PKCS11_MODULE_PATH=/path/to/libykcs11.so openssl rsautl -engine pkcs11 -keyform engine -inkey "pkcs11:object=Private key for PIVAuthentication;type=private" -sign -in data.txt -out data.sig Where -- ``object=Private key for PIVAuthentication`` specifies the alias (or label) of the private key to be used. The aliases of the keys stored on the YubiKey PIV are fixed and unmodifiable. See :ref:`piv-tool-ykcs11-objects`. .. code:: type=private specifies that the type of the object is a private key (CKA_CLASS = CKO_PRIVATE_KEY) For more parameters to specify keys see `RFC7512 `_. .. Caution:: Be aware that the order of the parameters in the command line can be important.