Generic PKCS#11 Provider
EJBCA supports two ways t connect to HSMs using the PKCS#11 API, the Java PKCS#11 Provider and P11-NG.
There is a PKCS#11 wrapper in Java used to implement support for tokens with PKCS#11 libraries, commonly referred to as the Java PKCS#11 Provider. The Java PKCS#11 provider has at some stage been tested with HSMs described here, in various firmware and software versions (as well as some that are not described). For information on support for specific versions, consult support or other documentation. Java updates to the PKCS#11 provider may break support out of our control.
Note that the Java PKCS#11 provider caches PKCS#11 sessions in a way that they can not be re-established. If the connection to the HSM is broken, it
will require a restart of the application server. This is an unfortunate function of how the Java PKCS#11 provider is implemented in Java.
Besides the keys described in Hardware Security Modules (HSM), the Crypto Token property field (matching with user friendly values of the Crypto Token in the Administration GUI) should contain the following properties:
sharedLibrary: Path to the HSM PKCS#11 library (/etc/utimaco/libcs2_pkcs11.so, /usr/safenet/lunaclient/lib/libCryptoki2_64.so etc)
slotLabelType: Type of slot reference, see below
slotLabelValue: Value of the slot reference (1, myslot etc).
The slot label type can be one of the following
SLOT_NUMBER: Any positive integer, can be used to refer to slots in any HSM with consecutive slot numbering.
SLOT_INDEX: Any positive integer, prefaced by an 'i'.
SLOT_LABEL: The PKCS#11 standard allows for using strings for labeling slots. This label may also be an integer or an 'i' followed by an integer (like a number or an index)
SUN_FILE: The slot specified by a SUN config file. The slot label can be left blank.
Optionally a few extra properties fields can be used:
attributesFile: A file specifying PKCS#11 attributes (used mainly for key generation).
keyspec: Key specification used when generating new HSM keys from within the admin GUI. Keyspec that is used as first choice when generating new keys in the GUI of form "1024" for RSA keys, "DSA1024" for DSA keys and secp256r1 for EC keys. If keyspec is not given EJBCA tries to generate a key with the same specification as the current cert signing key.
An attributes file is in the format specified in the JavaTM PKCS#11 Reference Guide.
If no attributesFile is specified, a built-in default configuration is used (as of EJBCA 3.11). Generally, you should NOT use an attributesFile and thus only in exceptional cases using an uncommon HSM not working well with the defaults.
The following shows an example of an 'attributesFile' (that should not be used) which will give generated keys same attribute values as the default:
name=SafeNet
library=
/opt/PTK/lib/libcryptoki
.so
slot=1
attributes(*, CKO_PUBLIC_KEY, *) = {
CKA_TOKEN =
false
CKA_ENCRYPT =
true
CKA_VERIFY =
true
CKA_WRAP =
true
}
attributes(*, CKO_PRIVATE_KEY, *) = {
CKA_TOKEN =
true
CKA_PRIVATE =
true
CKA_SENSITIVE =
true
CKA_EXTRACTABLE =
false
CKA_DECRYPT =
true
CKA_SIGN =
true
CKA_UNWRAP =
true
CKA_DERIVE =
false
}
disabledMechanisms = {
CKM_SHA1_RSA_PKCS
CKM_SHA256_RSA_PKCS
CKM_SHA384_RSA_PKCS
CKM_SHA512_RSA_PKCS
CKM_MD2_RSA_PKCS
CKM_MD5_RSA_PKCS
CKM_DSA_SHA1
CKM_ECDSA_SHA1
}
The only known occasion where the default is not working is when the module protected slot of a Thales/nCipher HSM is used and the file must then exist and have CKA_PRIVATE = false (see below).
The default attributes that are applied to each key generated by EJBCA will assure that:
All needed operations could be done.
The private part of the key is stored in the HSM but not the public part (which is in a certificate that is stored on the HSM).
It will be impossible to read the private part of the key from the HSM.
The default configuration will also disable certain signing mechanisms. The disabled mechanisms are for signing when the data to be signed is hashed by PKCS#11 before using the private key in the HSM. When these mechanisms are disabled, the sun PKCS#11 wrapper provider will do the hashing instead of the HSM. This speeds up the signing in most cases, especially when your HSM is on another host and will not have any security impacts as no secret in the HSM is used for the hashing.
However, it will be possible not to disable these hash/signing mechanisms, see the PKCS#11 section of '$EJBCA_HOME/conf/cesecore.properties'. You could try not to disable the mechanisms if you get the error CKR_FUNCTION_NOT_SUPPORTED (0x54) from PKCS#11 when signing.
If you are using an attributesFile and have more than one CA using the same slot it is very important that BOTH CA token properties configurations contain the attributesFile. This is because the attributes are applied when the provider is installed during startup. If one configuration does not have the attributesFile it cannot be applied later on by the other configuration.
The tool EJBCA_HOME/dist/clientToolBox/ejbcaClientToolBox.sh PKCS11HSMKeyTool is used to administrate and generate keys. Use it without parameters to get all valid options. Keys are generated either using a default specified slot and PKCS#11 library or using a configuration file.
To generate keys using the built-in default with a specified slot and PKCS#11 library, use:
dist
/clientToolBox/ejbcaClientToolBox
.sh PKCS11HSMKeyTool generate hsmp11.so 2048 defaultKey 1
To generate keys using a configuration file, use:
dist
/clientToolBox/ejbcaClientToolBox
.sh PKCS11HSMKeyTool generate hsmp11.conf 2048 defaultKey
The contents of the configuration file is specified in the PKCS#11 wrapper documentation from Oracle. Generally, it is sufficient to use the default but with some HSMs, it may be necessary to define certain PKCS#11 attributes for the generated key.
Note that all keys to be used have to be generated prior to the application server is started.
The default attributes attempt to automatically set CKA_LABEL also when generating keys using the clientToolBox. You can set CKA_LABEL, which is hex encoded characters, also with an attributesFile, either by setting the CKA_LABEL value:
attributes(*, CKO_PRIVATE_KEY, *) = {
CKA_TOKEN =
true
...
CKA_LABEL = 0h707269762d6b65796c6162656c
}
or by setting an empty CKA_LABEL string with two spaces before and nothing, not even space after. This placeholder will then be dynamically replaced with the key alias value, hex encoded:
attributes(*, CKO_PRIVATE_KEY, *) = {
CKA_TOKEN =
true
...
CKA_LABEL
}
Generated HSM Objects
EJBCA needs (via the Java PKCS#11 provider) two object on the HSM, which are all generated by the generate commands above:
A private key
A certificate, thus a holder of the public key used by Java, and not the real certificate of a CA.
A Java keystore entry has no reference to a public key pkcs#11 object, just a private key object and a certificate object, hence the public key object is not needed after the certificate object has been written to the keystore. By setting the CKA_TOKEN attribute to false for the public key its object will not be stored on the HSM. If CKA_TOKEN is true then all public keys will be on the HSM forever since no public key is deleted when a private key is deleted from the keystore. So in order not to waste memory on the HSM CKA_TOKEN must be false for the public key.
When generating keys with clientToolBox each private key has the CKA_LABEL attribute set to the alias of the key prefixed with priv-. But when generating a key in EJBCA there will normally not be a CKA_LABEL for the private key. If you want to have a label even when the key is generated by EJBCA you got to use an attribute file with a CKA_LABEL definition in your configuration. The value of the attribute is a hexadecimal string starting with "0h". These labels are normally seen only when you use the native HSM tools to list and manipulate objects. CKA_LABEL is set on the certificate object, and this is the label used as an alias in Java/EJBCA. The PKCS#11 attribute CKA_ID binds a certificate object (public key) to the private key.
The above example would then include:
attributes(*,CKO_PRIVATE_KEY,*) = {
.
.
CKA_LABEL = 0h6b657931
}
The example above gives the label key1 to the private key. You can give any label by looking up the hex codes of characters in the ascii table.