Net iD Service

PKCS#11

Page updated: 2023-07-07


What it is

PKCS#11 is a cryptographic token interface standard, which specifies an API, called Cryptoki.
PKCS#11 was developed by the RSA Labs but is now an open standard managed by the OASIS PKCS 11 Technical Committee.
https://www.oasis-open.org/committees/pkcs11/

If you want to have support for multiple platforms, and you know what you do, PKCS#11 can be a good choice for buildning an application using certificates.

 

Version

The current version of the standard is 2.40, but our implementation will return 2.11 as version information.

The differences between the two versions are:
a) Algorithm extensions not concerning smart cards
b) Changed suggestion for handling multiple PINs. The suggestion regarding multiple PINs is useless and will be removed in future versions of the standard.

The implementation in Net iD Enterprise and Net iD Client is very stable and we seldom need to change anything. The last change was the addition of PKCS#11 key attribute CKA_ALWAYS_AUTHENTICATE in 6.8.4.10.

Applications implementing the standard should only be concerned with the major version (2) and minor versions adding support for specific algorithms which are needed, i.e. in those rare cases where a new specific algorithm is mandatory.

 

Third-party Package

The PKCS#11 library may be installed in any location; it has no other binary dependencies, and only needs the configuration file for license information.
For library version 5.4 and later the configuration file may be included in the binary, there is no need for a separate file.

 

Example

The example will test three standard operations with a smart card: create/verify a digital signature, encrypt/decrypt a message and wrap/unwrap a secret key. The example uses Microsoft Developer Studio, but is written in standard C and should be possible to compile using any compiler. Download sample code:

Link your application to Pointsharps PKCS#11 implementation

Net iD Enterprise
Windows => iidp11.dll
Linux => libiidp11.so
macOS => libiidp11.dylib

Net iD Client
Windows => netid.dll
Linux => libnetid.so
macOS => /usr/local/lib/netid/libnetid.dylib

a) You should list all available slots (C_GetSlotList)
b) Then open a session for every found slot and search for all certificates in all slots.
c) When all certificates have been collected check them against the rules set up by your application and the context.
d) If you get more than one hit you should present a decent dialog where the user can select a certificate.
e) Then proceed with the desired operations.
Details can be found here: https://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html

 

Cryptoki specifications

Version major minor
1.0 0x01 0x00
2.01 0x02 0x01
2.10 0x02 0x0a
2.11 0x02 0x0b
2.20 0x02 0x14
2.30 0x02 0x1e
2.40 0x02 0x28

 

Prefixes

Prefix Description
C_ Function
CK_ Data type or general constant
CKA_ Attribute
CKC_ Certificate type
CKD_ Key derivation function
CKF_ Bit flag
CKG_ Mask generation function
CKH_ Hardware feature type
CKK_ Key type
CKM_ Mechanism type
CKN_ Notification
CKO_ Object class
CKP_ Pseudo-random function
CKS_ Session state
CKR_ Return value
CKU_ User type
CKZ_ Salt/Encoding parameter source
h a handle
ul a CK_ULONG
p a pointer
pb a pointer to a CK_BYTE
ph a pointer to a handle
pul a pointer to a CK_ULONG

 

PKCS#11 Error Codes

Name HEX DEC
CKR_OK 0x00000000  
CKR_CANCEL 0x00000001  
CKR_HOST_MEMORY 0x00000002  
CKR_SLOT_ID_INVALID 0x00000003  
CKR_GENERAL_ERROR 0x00000005  
CKR_FUNCTION_FAILED 0x00000006  
CKR_ARGUMENTS_BAD 0x00000007  
CKR_NO_EVENT 0x00000008  
CKR_NEED_TO_CREATE_THREADS 0x00000009  
CKR_CANT_LOCK 0x0000000A  
CKR_ATTRIBUTE_READ_ONLY 0x00000010  
CKR_ATTRIBUTE_SENSITIVE 0x00000011  
CKR_ATTRIBUTE_TYPE_INVALID 0x00000012  
CKR_ATTRIBUTE_VALUE_INVALID 0x00000013  
CKR_DATA_INVALID 0x00000020  
CKR_DATA_LEN_RANGE 0x00000021  
CKR_DEVICE_ERROR 0x00000030 48
CKR_DEVICE_MEMORY 0x00000031 49
CKR_DEVICE_REMOVED 0x00000032  
CKR_ENCRYPTED_DATA_INVALID 0x00000040  
CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041  
CKR_FUNCTION_CANCELED 0x00000050  
CKR_FUNCTION_NOT_PARALLEL 0x00000051  
CKR_FUNCTION_NOT_SUPPORTED 0x00000054  
CKR_KEY_HANDLE_INVALID 0x00000060  
CKR_KEY_SIZE_RANGE 0x00000062  
CKR_KEY_TYPE_INCONSISTENT 0x00000063  
CKR_KEY_NOT_NEEDED 0x00000064  
CKR_KEY_CHANGED 0x00000065  
CKR_KEY_NEEDED 0x00000066  
CKR_KEY_INDIGESTIBLE 0x00000067  
CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068  
CKR_KEY_NOT_WRAPPABLE 0x00000069  
CKR_KEY_UNEXTRACTABLE 0x0000006A  
CKR_MECHANISM_INVALID 0x00000070  
CKR_MECHANISM_PARAM_INVALID 0x00000071  
CKR_OBJECT_HANDLE_INVALID 0x00000082  
CKR_OPERATION_ACTIVE 0x00000090 144
CKR_OPERATION_NOT_INITIALIZED 0x00000091  
CKR_PIN_INCORRECT 0x000000A0 160
CKR_PIN_INVALID 0x000000A1 161
CKR_PIN_LEN_RANGE 0x000000A2  
CKR_PIN_EXPIRED 0x000000A3  
CKR_PIN_LOCKED 0x000000A4 164
CKR_SESSION_CLOSED 0x000000B0  
CKR_SESSION_COUNT 0x000000B1  
CKR_SESSION_HANDLE_INVALID 0x000000B3  
CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4  
CKR_SESSION_READ_ONLY 0x000000B5  
CKR_SESSION_EXISTS 0x000000B6  
CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8  
CKR_SIGNATURE_INVALID 0x000000C0  
CKR_SIGNATURE_LEN_RANGE 0x000000C1  
CKR_TEMPLATE_INCOMPLETE 0x000000D0  
CKR_TEMPLATE_INCONSISTENT 0x000000D1  
CKR_TOKEN_NOT_PRESENT 0x000000E0 224
CKR_TOKEN_NOT_RECOGNIZED 0x000000E1  
CKR_TOKEN_WRITE_PROTECTED 0x000000E2  
CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0  
CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1  
CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2  
CKR_USER_ALREADY_LOGGED_IN 0x00000100 256
CKR_USER_NOT_LOGGED_IN 0x00000101 257
CKR_USER_PIN_NOT_INITIALIZED 0x00000102  
CKR_USER_TYPE_INVALID 0x00000103  
CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104  
CKR_USER_TOO_MANY_TYPES 0x00000105  
CKR_WRAPPED_KEY_INVALID 0x00000110  
CKR_WRAPPED_KEY_LEN_RANGE 0x00000112  
CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113  
CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114  
CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115  
CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120  
CKR_RANDOM_NO_RNG 0x00000121  
CKR_DOMAIN_PARAMS_INVALID 0x00000130  
CKR_BUFFER_TOO_SMALL 0x00000150 336
CKR_SAVED_STATE_INVALID 0x00000160  
CKR_INFORMATION_SENSITIVE 0x00000170  
CKR_STATE_UNSAVEABLE 0x00000180  
CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190  
CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191  
CKR_MUTEX_BAD 0x000001A0  
CKR_MUTEX_NOT_LOCKED 0x000001A1  
CKR_VENDOR_DEFINED 0x80000000  

 

Defined mechanism types for Cryptoki

Not yet in place. See the standard itself.

 

Sample 1 - How PKCS#11 can look like

An application using PKCS#11 to list slots and their eventual content

 

Sample 2 - An application talks PKCS#11

Another application using PKCS#11 to list slots and their eventual content