The most important object classes are those that implement keys: private keys (CKO_ PRIVATE_KEY), public keys (CKO_PUBLIC_ KEY) and secret keys (CKO_SECRET_KEY). Private and public keys are the members of an asymmetric key pair whereas secret keys are symmetric keys or MAC keys.
There are many key-specific attributes. For example, the Boolean attribute CKA_WRAP denotes whether a key may be used to wrap another key. The Boolean attribute CKA_SENSITIVE is only applicable for private and secret keys and if the value of CKA_SENSITIVE is set to true, the value of the key may never be revealed in clear text. CKA_MODULUS is an attribute specific to RSA keys. Not all tokens support all key types with all possible attributes.
Object management functions to create keys are C_GenerateKey(), C_GenerateKeyPair() and C_DeriveKey(). To import a key not generated by one of these three functions, C_CreateObject() is used with all key-specific attributes defined. Alternatively, a wrapped key can be imported with C_Unwrap() where a wrapped key is a standard representation of a key specific to the key type (e.g., a byte array for secret keys or a BER encoding for other key types) that’s encrypted by a wrapping key.
PKCS#11 also defines objects for certificates. However, no functions to operate on certificates are part of the PKCS#11 API.
Additional PKCS#11 Concepts
Each program using PKCS#11 must call C_Initialize() once before calling any other PKCS#11 function. C_Initialize() takes as arguments information on the threading capabilities required and optionally call-back functions (i.e., MUTEX functions) to be used for the synchronization of multiple threads. The end of all PKCS#11 processing should be indicated with C_Finalize().
For many hardware tokens, a PIN entry is required at the physical token (e.g., at a smart card reader in an ATM). If the CKF_PROTECTED_AUTHENICATION_ PATH flag of the PKCS#11 token is set by the program, the C_Login() function takes a NULL_PTR as the PIN argument and blocks until the PIN has been entered at the hardware token.
Putting It All Together
Figure 5 shows a skeleton of a typical program using PKCS#11 where within a session one or more cryptographic operations may be performed. For example, encrypting a message spread over multiple buffers could look like Figure 6.
OpenCryptoki is an open source implementation of PKCS#11 version 2.2 in the C programming language meant to run on the Linux operating system. The project is maintained by the IBM Linux Technology Center and hosted on SourceForge (http://sourceforge.net/projects/opencryptoki). The latest versions are version 188.8.131.52 available with RHEL 6 and SLES 11 Linux distributions, and version 3.1, which hasn’t yet been picked up by any distribution.