Identifiers and Labels in PKCS#11
The PKCS#11 standard has multiple "id" attributes and a "label" attribute. These are often confused and mis-understood, especially with respect to their uniqueness requirements.
This table summarises the most common identifier attributes:
| Attribute | Use case | Unique? | Set by | Notes |
|---|---|---|---|---|
CKA_LABEL | Human-readable string. | No | Application | An array of CK_UTF8CHAR. |
CKA_ID | An identifier. Often used to logically group together private keys, public keys, and certificates. For example, the ID can be the hash of the public key (the fingerprint). | No | Application | An array of CK_BYTE, thus not required to be a string. |
CKA_OBJECT_ID | "Object" in the "OID" sense. Not to be confused with a PKCS#11 object. Used in data objects (CKO_DATA, storing application-defined data) for indicating the object type. | No | Application | Not supported by the Primus PKCS#11 provider. |
CKA_UNIQUE_ID | Persistent, unique ID for an object on the token. | Yes | Token/HSM | Added in the PKCS#11 3.0 standard. Not supported by the Primus PKCS#11 provider. |
Uniqueness
The PKCS#11 standard does not require CKA_LABEL and CKA_ID to be unique (as seen in the table).
It is up to the application to choose a scheme and manage these attributes.
The application needs to make sure that its addressing scheme is able to uniquely identify objects.
For example, an application might have a private key, public key, and certificate all with the same
CKA_LABEL and CK_ID, and uses the CK_OBJECT_CLASS (see the CKO_xyz definitions) to distinguish the three objects.
If you are in a situation where your application has created duplicates, you need to iterate over them and manually try to find out which is the one you are looking for.
Uniqueness in Primus HSM
Internally, the Primus HSM requires labels (CKA_LABEL) to be unique for a given "category" of object.
The categories roughly match CKA_CLASS and are defined as follows:
- Public key
- Secret/private/SKA/RKS key
- Certificate
- Data object
Within each of these four categories, Primus HSM requires a label to be unique.
Labels must also be non-empty.
When an application creates an object and does not provide a CKA_LABEL,
the provider uses the hex-encoding of the CKA_ID as the label.
If CKA_ID is also not provided, the provider uses a random hex string as the label.
Label Suffixes in Primus HSM
Therefore, the Primus PKCS#11 provider needs to smooth over the fact that on one side the PKCS#11 standard allows two private keys to have the same label but on the other side Primus HSM rejects it.
The Primus PKCS#11 provider handles these cases by transparently adding suffixes to labels. This works as follows:
- When creating objects, the provider first tries to create the object with the label provided by the application.
If the HSM rejects this operation due to a duplicate label, the provider adds
a random, unique suffix to the label and retries the operation.
This new label has the form
label@?!<uid>.- For example, if you create three objects with the same label, only the first object will be created on the HSM with this label. This first object will NOT have a suffix. The second and third object will be created with labels that have suffixes.
- When looking up objects,
C_FindObjectsreturns all objects that match the label in the search template (and any other conditions, if provided). The provider strips any suffixes, and returns the objects as all having the same label.
These suffixes are an implementation detail, and are not exposed via the PKCS#11 interface. However, these suffixes are visible via other API providers (such as JCE) or in other contexts (for example, when exporting a list of invalidated keys from the HSM).
unique_label Flag
Primus PKCS#11 Provider 2.7.0 introduced the unique_label config flag. It behaves as follows:
- If false (default), the provider behaves as described above, to be standard-compliant.
- If true, the suffix-workaround is disabled.
- Creating objects with duplicate labels will fail with
CKR_HSM_DUPLICATE_ENTRY(0x80000003). - Looking up objects will only return exact matches.
Objects with the same label plus a suffix (created by earlier versions
or with
unique_label=false) will not be returned. - These objects can still be found if you provide the full label as seen by Primus HSM (that is, including the suffix).
- When querying the
CKA_LABELattribute of an object withC_GetAttributeValue, any suffixes that may be present are not stripped. The full label as received from the HSM is returned to the application.
- Creating objects with duplicate labels will fail with
With unique_label=true, objects can still have the same CKA_LABEL
as long as they have a different category (as defined above).
For applications that do not rely on the PKCS#11 standard's behaviour of allowing
duplicately labelled objects (of the same type), we recommend to set unique_label=true.
This significantly speeds up object lookup, especially for large partitions with more than 10K objects.
This is because the provider can directly index the object by label, instead of searching the keystore.
Null-termination
In PKCS#11, strings do not have null termination.
This applies to both CK_CHAR and CK_UTF8CHAR.
Thus in practice, you will often find yourself specifying labels as follows:
{CKA_LABEL, label, sizeof(label)-1},
The Primus PKCS#11 provider will also remove any null-termination (\0) of labels.
Still, for compliance with the PKCS#11 standard and better portability,
Securosys recommends to not pass null-terminators to the PKCS#11 library.