is an open standard C API that provides a means to access cryptographic capabilities on a device.
For example, it is often used to access a Hardware Security Module (HSM) (like a [Yubikey](https://www.yubico.com/)) from a local program (such as [GPG](https://gnupg.org/)).
Vault provides a PKCS#11 library (or provider) so that Vault can be used as an SSM (Software Security Module).
This allows a user to treat Vault like any other PKCS#11 device to manage keys, objects, and perform encryption and decryption in Vault using PKCS#11 calls.
The certificate file from the KMIP Secrets Engine also contains the key.
1. Create a configuration file called `vault-pkcs11.hcl`:
```hcl
slot {
server = "127.0.0.1:5696"
tls_cert_path = "cert.pem"
ca_path = "ca.pem"
scope = "my-service"
}
```
See [below](#configuration) for all available parameters.
1. Copy the certificates from the KMIP credentials into the files specified in the configuration file (e.g., `cert.pem`, and `ca.pem`).
1. You should now be able to use the `libvault-pkcs11.so` (or `.dylib`) library to access the KMIP Secrets Engine in Vault using any PKCS#11-compatible tool, like OpenSC's `pkcs11-tool`, e.g.:
to Vault instances and KMIP scopes and configures how the library will authenticate to KMIP (with a client TLS certificate).
The PKCS#11 library will look for this file in `vault-pkcs11.hcl` and `/etc/vault-pkcs11.hcl` by default, or you can override this by setting the `VAULT_KMIP_CONFIG` environment variable.
For example,
```hcl
slot {
server = "127.0.0.1:5696"
tls_cert_path = "cert.pem"
ca_path = "ca.pem"
scope = "my-service"
}
```
The `slot` block configures the first PKCS#11 slot to point to Vault.
Most programs will use only one slot.
- `server` (required): the Vault server's IP or DNS name and port number (5696 is the default).
- `tls_cert_path` (required): the location of the client TLS certificate used to authenticate to the KMIP engine.
- `tls_key_path` (optional, defaults to the value of `tls_cert_path`): the location of the encrypted or unencrypted TLS key used to authenticate to the KMIP engine.
- `ca_path` (required): the location of the CA bundle that will be used to verify the server's certificate.
- `scope` (required): the [KMIP scope](/vault/docs/secrets/kmip#scopes-and-roles) to authenticate against and where the TDE master keys and associated metadata will be stored.
- `cache` (optional, default `true`): if the provider uses a cache to improve the performance of `C_GetAttributeValue` (KMIP: `GetAttributes`) calls.
- `emulate_hardware` (optional, default `false`): specifies if the provider should report that it is connected to a hardware device.
The default location the PKCS#11 library will look for the configuration file is the current directory (`vault-pkcs11.hcl`) and `/etc/vault-pkcs11.hcl`, but you can override this by setting the `VAULT_KMIP_CONFIG` environment variable to any file.
Environment variables can be also used to configure these parameters and more.
- `VAULT_KMIP_CONFIG`: location of the HCL configuration file. By default, the provider will check `./vault-pkcs11.hcl` and `/etc/vault-pkcs11.hcl`.
- `VAULT_KMIP_CERT_FILE`: location of the TLS certificate used for authentication to the KMIP engine.
- `VAULT_KMIP_KEY_FILE`: location of the TLS key used for authentication to the KMIP engine.
- `VAULT_KMIP_KEY_PASSWORD`: password for the TLS key file, if it is encrypted to the KMIP engine.
- `VAULT_KMIP_CA_FILE`: location of the TLS CA bundle used to authenticate the connection to the KMIP engine.
- `VAULT_KMIP_SERVER`: address and port of the KMIP engine to use for encryption and storage.
- `VAULT_KMIP_SCOPE`: KMIP scope to use for encryption and storage
- `VAULT_KMIP_CACHE`: whether or not to cache `C_GetAttributeValue` (KMIP: `GetAttributes`) calls.
- `VAULT_LOG_LEVEL`: the log level that the provider will use. Defaults to `WARN`. Valid values include `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, and `OFF`.
- `VAULT_LOG_FILE`: the location of the file the provider will use for logging. Defaults to standard out.
- `VAULT_EMULATE_HARDWARE`: whether or not the provider will report that it is backed by a hardware device.
## Encrypted TLS Key Support
The TLS key returned by the KMIP engine is unencrypted by default.
However, the PKCS#11 provider does support (limited) encryption options for the key using [RFC 1423](https://www.rfc-editor.org/rfc/rfc1423).
We would only recommend using AES-256-CBC out of the available algorithms.
The keys from KMIP should be ECDSA keys, and can be encrypted with a password with OpenSSL, e.g.,:
The PKCS#11 provider will need access to the password to decrypt the TLS key.
The password can be supplied to the provider in two ways:
- The `VAULT_KMIP_KEY_PASSWORD` environment variable, or
- the "PIN" parameter to the `C_Login` PKCS#11 function will be used to try to decrypt an encrypted TLS key.
Note that only a single password can be supplied via the `VAULT_KMIP_KEY_PASSWORD`, so if multiple slots in the HCL file use encrypted TLS keys, they will need to be encrypted with the same password, or use the `C_Login` method to specify the password.
## Error Handling
If an error occurs, the first place to check will be the `VAULT_LOG_FILE` for any relevant error messages.
If the PKCS#11 provider returns an error code of `0x30` (`CKR_DEVICE_ERROR`), then an additional device error code may
be available from the `C_SessionInfo` call.
Here are the known device error codes the provider will return:
Due to the nature of Vault, the KMIP Secrets Engine, and PKCS#11, there are some other limitations to be aware of:
- The key and object IDs returned by `C_FindObjects`, etc., are randomized for each session, and cannot be shared between sessions; they have no meaning after a session is closed.
This is because KMIP objects, which are used to store the PKCS#11 objects, have long random strings as IDs, but the PKCS#11 object ID is limited to a 32-bit integer. Also, the PKCS#11 provider does not have any local storage.
- The PKCS#11 provider's performance is heavily dependent on the latency to the Vault server and its performance.
This is because nearly all PKCS#11 API calls are translated 1-1 to KMIP calls, aside from some object attribute calls (which can be locally cached).
Multiple sessions can be safely used simultaneously though, and a single Vault server node has been tested as supporting thousands of ongoing sessions.
- The object attribute cache is valid only for a single object per session, and will be cleared when another object's attributes are queried.
- The random number generator function, `C_GenerateRandom`, is currently implemented in software in the library by calling out to Go's [`crypto/rand`](https://pkg.go.dev/crypto/rand) package,