HID® Crescendo® PKCS11
c_hid.h File Reference
#include <pkcs11/v2.40/cryptoki.h>

Macros

#define CKM_UNBLOCK_PIN_DYNAMIC   (CKM_UNBLOCK_PIN_STATIC + 1)
 
#define CKM_UNBLOCK_PIN_STATIC   (CKM_VENDOR_DEFINED + 0x801)
 HID proprietary mechanism used to unblock a PIN using a PUK code. More...
 

Functions

AC_EXPORT CK_RV C_VerifyUnblockPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen, CK_UTF8CHAR_PTR pPuk, CK_ULONG ulPukLen)
 Performs a PIN unblock operation, which was previously initialized by C_VerifyUnblockPINInit. More...
 
AC_EXPORT CK_RV C_VerifyUnblockPINInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hPuk)
 Initializes a PIN unblock operation. More...
 

Macro Definition Documentation

◆ CKM_UNBLOCK_PIN_DYNAMIC

#define CKM_UNBLOCK_PIN_DYNAMIC   (CKM_UNBLOCK_PIN_STATIC + 1)

◆ CKM_UNBLOCK_PIN_STATIC

#define CKM_UNBLOCK_PIN_STATIC   (CKM_VENDOR_DEFINED + 0x801)

HID proprietary mechanism used to unblock a PIN using a PUK code.

Function Documentation

◆ C_VerifyUnblockPIN()

AC_EXPORT CK_RV C_VerifyUnblockPIN ( CK_SESSION_HANDLE  hSession,
CK_UTF8CHAR_PTR  pNewPin,
CK_ULONG  ulNewLen,
CK_UTF8CHAR_PTR  pPuk,
CK_ULONG  ulPukLen 
)

Performs a PIN unblock operation, which was previously initialized by C_VerifyUnblockPINInit.

Parameters
[in]hSessionis the session's handle.
[in]pNewPinis a pointer to a buffer containing the new (utf-8 encoded) PIN
[in]ulNewLenis the size of the new PIN buffer
[in]pPukis a pointer to a buffer containing the (utf-8 encoded) PUK code
[in]ulPukLenis the size of the PUK code buffer
Note
A successful call will not change the authentication state of the session.
The session must be a RW (read-write) session
If a wrong PUK code is provided, the function will return CKR_USER_NOT_LOGGED_IN
See also
C_VerifyUnblockPINInit
Returns
  • CKR_OK on success.
  • One of the following error codes on failure:
    CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_SESSION_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID, CKR_PIN_INVALID, CKR_ACTION_PROHIBITED, CKR_GENERAL_ERROR, CKR_USER_NOT_LOGGED_IN, CKR_DEVICE_ERROR, CKR_DEVICE_REMOVED

◆ C_VerifyUnblockPINInit()

AC_EXPORT CK_RV C_VerifyUnblockPINInit ( CK_SESSION_HANDLE  hSession,
CK_MECHANISM_PTR  pMechanism,
CK_OBJECT_HANDLE  hPuk 
)

Initializes a PIN unblock operation.

Parameters
[in]hSessionis the session's handle.
[in]pMechanismpoints to the unblock mechanism
[in]hPukan object handle for the PUK object to unlock the PIN with

Currently, only the proprietary CKM_UNBLOCK_PIN_STATIC mechanism with no parameters is supported.

This is a proprietary extension which allows unblocking the PIN corresponding to the CKU_USER role after it was blocked, e.g. because of too many incorrect login attempts. This will typically be the application PIN for PIV tokens. The unblocking is done using a PUK (PIN Unlock) code stored on the card and provided to the user when initializing the card.

The unblock operation proceeds in two steps. First this method (C_VerifyUnblockPINInit) needs to be called with a handle to the PUK object (and the CKM_UNBLOCK_PIN_STATIC mechanism). Next the actual unblocking is performed by calling the method C_VerifyUnblockPIN and providing it the PUK code. This can be done, e.g. (omitting any error handling), as follows:

// Find the PUK object
std::string label = "Object::UNBLOCKING_PIN";
CK_KEY_TYPE type_generic_secret = CKK_GENERIC_SECRET;
CK_ATTRIBUTE unblock_pin_template[] = {
{CKA_KEY_TYPE, (void*)&type_generic_secret, sizeof(type_generic_secret)}
{CKA_LABEL, (void*)label.data(), (CK_ULONG)label.size()},
};
CK_RV rv = C_FindObjectsInit(session, unblock_pin_template, 1);
CK_OBJECT_HANDLE hPuk[1];
CK_ULONG puk_count = 0;
rv = C_FindObjects(session, hPuk, 1, &puk_count);
// Initialize the Unblock operation
CK_MECHANISM mech {
.mechanism = CKM_UNBLOCK_PIN_STATIC,
.pParameter = nullptr,
.ulParameterLen = 0,
};
rv = p11lib->C_VerifyUnblockPINInit(session, &mech, hPuk);
// Reset the pin to "xxxxxx" using the PUK "12345678"
std::string new_pin = "xxxxxx";
std::string puk = "12345678";
C_VerifyUnblockPIN(session, (CK_UTF8CHAR_PTR)new_pin.c_str(), new_pin.size(), puk.data(), puk.size());
#define CKM_UNBLOCK_PIN_STATIC
HID proprietary mechanism used to unblock a PIN using a PUK code.
Definition: c_hid.h:13
AC_EXPORT CK_RV C_VerifyUnblockPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen, CK_UTF8CHAR_PTR pPuk, CK_ULONG ulPukLen)
Performs a PIN unblock operation, which was previously initialized by C_VerifyUnblockPINInit.
CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
Continues a search for token and session objects that match a template, obtaining additional object h...
CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
Terminates a search for token and session objects.
CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
Initializes a search for token and session objects that match a template.
T c_str(T... args)
T data(T... args)
T size(T... args)
Note
The PUK code (at least for PIV cards) will typically be 8 bytes long.
The internal implementation represents all token "roles" as P11 objects which have a CK_KEY_TYPE attribute equal to CKK_GENERIC_SECRET. In particular the C_FindObjects call in the example above will typically return, at least, objects corresponding to the CKU_USER and CKU_SO roles. Therefore the we filter the objects looking for an object with label "Object::UNBLOCKING_PIN", which should correspond to the PIN Unblocking role — the PUK object.
When the user is logged in to the token, the PUK code can be read from the CKA_VALUE attribute of the PUK object using C_GetAttributeValue, e.g.:
// Read the PUK code (given a handle to the PUK object)
CK_ATTRIBUTE puk_info_tpl[] = {
{CKA_VALUE, (void*)puk.data(), (CK_ULONG)puk.size()},
};
// if puk_handle refers to a non-puk role (e.g. CKU_USER), the following
// call will return an error (currently @ref CKR_FUNCTION_NOT_SUPPORTED)
CK_RV rv = C_GetAttributeValue(session, puk_handle, puk_info_tpl, sizeof(puk_info_tpl)/sizeof(CK_ATTRIBUTE));
puk.resize(puk_info_tpl[1].ulValueLen);
CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
Obtains the value of one or more attributes of an object.
T resize(T... args)
Returns
  • CKR_OK on success.
  • One of the following error codes on failure:
    CKR_ARGUMENTS_BAD, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID, CKR_SESSION_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID, CKR_DEVICE_REMOVED