This page documents areas where, as one commentator said at the first PKCS #11 TC meeting, "the documentation appears to set things out clearly and then goes on to completely muddle the issue".


The inconsistent use of CKA_ID and CKA_LABEL provides major headaches for users, with applications having to perform extremely complex silly-walks to locate (for example) a certificate corresponding to a private key, or even just a private key. The documentation should be changed to make CKA_ID mandatory for all objects, with all related objects (e.g. private key and associated certificate) being linked via a common CKA_ID, and to make CKA_LABEL mandatory for at least private-key objects.


There are two ways to indicate a key generation capability, either CKF_GENERATE_KEY or CKM_GENERATE_KEY or both. Implementations apply these in more or less arbitrary ways. Some sort of consistency for these would be nice.

Not sure what's best here.


Use of these two is muddled, for example a token may advertise one but do the other. This is both a bug and a clarification, but can be fixed with a clarification, "If you do CKM_RSA_PKCS then you must also do CKM_RSA_X_509" (or in IETF terms "MUST CKM_RSA_X_509, MAY CKM_RSA_PKCS". Users can always do their own CKM_RSA_PKCS via CKM_RSA_X_509 if only CKM_RSA_X_509 is provided.

Inconsistency among usage attributes

Some objects are given very inconsistent usage attributes by devices, e.g. an object can encrypt/decrypt/sign but not verify. This causes two problems, if an implementation relies entirely on the token for its crypto capabilities then it can't use the token in that state, and since implementations perform probing of token capabilities in order to determine what's possible, the presence of such inconsistent capabilities tends to imply a buggy token/driver that can't safely be used. A solution would be to require that tokens present symmetric capabilities to users, e.g. if it provides an encryption capability then it should also provide a matching decryption capability.

C_FindObjectsInit and default attributes

C_FindObjectsInit: We should clarify that this clause applies to empty/default attributes as well: "The matching criterion is an exact byte-for-byte match with all attributes in the template."

C_FindObjectsInit and unknown attributes

C_FindObjectsInit: We should specify that a empty set of results should be returned when C_FindObjectsInit is used with attributes that the module doesn't know about. This is with thought to backwards compatibility, where a module implements an earlier version of the spec, and a caller uses a later version.

CKU_CONTEXT_SPECIFIC can be either user or key PIN

We should clarify that the PIN provided to a CKU_CONTEXT_SPECIFIC login may be the user pin, or may be a key specific PIN. No assumption should be made.

CKA_SERIAL_NUMBER clarification

The fact that CKA_SERIAL_NUMBER is the encoded DER TLV (and not just the contents) has had confusion, may be worth providing an example or something like: \x02\x02\x99\x88

Linux structure padding

We should mention that on Linux (and other Unixes?) that (while possible) no such byte-alignment is done. This was my very first PKCS#11 crasher.

Ephemeral handles

We should note that object handles and slot ids can and often will change between instances of an application, or once C_Finalize has been called. Various PKCS#11 callers take it for granted that these won't change.

Don't mention static linking as a security benefit

If an attacker can run/change the application or its libraries, then all bets are off. I don't think static linking is worth mentioning as a benefit of static linking. The spec can make no guarantees (explicit or imagined) here.


GetObjectSize: Should be able to return CK_UNAVAILABLE_INFORMATION especially if that was indicated in token info.

C_Logout and private handles

This clause is hard to implement and many module implementors do not implement it: "any of the application’s handles to private objects become invalid (even if a user is later logged back into the token, those handles remain invalid)". Is it useful?

C_CreateObject and other attribute templates

In a template when multiple attributes of a given type exist, we should define first attribute wins, or something consistent rather than leaving it open.

CK_C_INITIALIVE_ARGS.pReserved may be a string

CK_C_INITIALIZE_ARGS.pReserved is often used to for a module to accept an initialization string. Should we define a flag for this usage and bless it?

This is relevant to this part: "For this version of Cryptoki, the value of pReserved thereby obtained must be NULL_PTR; if it’s not, then C_Initialize should return with the value CKR_ARGUMENTS_BAD".

Creating session CKA_PRIVATE objects from RO session

We should document a consistent return value for the case when you try to create a session object with CKA_PRIVATE from a R/O session or SO session: Should fail with CKR_USER_NOT_LOGGED_IN, not CKR_TEMPLATE_INCONSISTENT.


This is not true: "Note that any attribute whose value is an array of attributes is identifiable by virtue of the attribute type having the CKF_ARRAY_ATTRIBUTE bit set." CK_ALLOWED_MECHANISMS also has this bit set, which is unfortunate because the template attributes really are different beasts than any other attribute, and it's worth having a bit to identify them.

DocumentClarifications (last edited 2013-03-21 15:22:48 by stefw)