Describe the Bug
CryptoTokenCreateCommand throws NullPointerException from Properties.setProperty when creating an Azure Key Vault crypto token via the EJB CLI without supplying the --azurevaultusekeybinding and --azurevaultkeybinding flags. Both flags are declared MandatoryMode.OPTIONAL, so users following the documented "App ID + Secret" auth path naturally leave them off, and the command crashes before the token is stored.
Root cause: in modules/ejbca-ejb-cli/src/org/ejbca/ui/cli/cryptotoken/CryptoTokenCreateCommand.java,
lines 247–248 set these properties unconditionally with values that can be null:
cryptoTokenPropertes.setProperty(AzureCryptoToken.KEY_VAULT_USE_KEY_BINDING, parameters.get(AZUREVAULT_USE_KEY_BINDING));
cryptoTokenPropertes.setProperty(AzureCryptoToken.KEY_VAULT_KEY_BINDING, parameters.get(AZUREVAULT_KEY_BINDING));
Properties.setProperty is backed by Hashtable.put, which throws NPE on null keys or null values.
The corresponding code path in the Admin Web UI (CryptoTokenMBean.java lines 1304–1311) handles the same fields correctly:
final String vaultKeyBinding = getCurrentCryptoToken().getKeyVaultKeyBinding();
properties.setProperty(AzureCryptoToken.KEY_VAULT_AUTHENTICATION_TYPE, getCurrentCryptoToken().getAzureAuthenticationType().toString());
if (vaultKeyBinding != null) {
properties.setProperty(AzureCryptoToken.KEY_VAULT_KEY_BINDING, vaultKeyBinding);
}
// Note: never sets KEY_VAULT_USE_KEY_BINDING, but uses the newer enum-based KEY_VAULT_AUTHENTICATION_TYPE only.
Two separate problems in the CLI:
- NPE: missing null-check before
setProperty for the two key-binding properties.
- Stale auth-mode handling: the CLI never sets
KEY_VAULT_AUTHENTICATION_TYPE. At runtime, AzureCryptoToken (cryptotokens-impl-3.0.0.jar) falls back to the legacy KEY_VAULT_USE_KEY_BINDING boolean only when KEY_VAULT_AUTHENTICATION_TYPE is absent. The CLI therefore can't currently create a managed-identity
crypto token at all, and even an App-ID-and-Secret token relies on the legacy fallback path. The CLI needs a new flag (e.g. --azurevaultauthtype APP_ID_AND_SECRET|KEY_BINDING|MANAGED_IDENTITY) that maps onto KEY_VAULT_AUTHENTICATION_TYPE.
To Reproduce
In an EJBCA CE 9.3.7 installation, with an Azure App Registration (client ID + secret) granted Key Vault Crypto User on a key in an AKV Premium vault:
ejbca.sh cryptotoken create \
--token RootCA-AKV \
--type AzureCryptoToken \
--autoactivate true \
--pin "<client-secret>" \
--azurevaultname my-keyvault \
--azurevaulttype premium \
--azurevaultclientid 11111111-2222-3333-4444-555555555555
Observed:
Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.concurrent.ConcurrentHashMap.putVal(Unknown Source)
at java.base/java.util.concurrent.ConcurrentHashMap.put(Unknown Source)
at java.base/java.util.Properties.put(Unknown Source)
at java.base/java.util.Properties.setProperty(Unknown Source)
at org.ejbca.ui.cli.cryptotoken.CryptoTokenCreateCommand.execute(CryptoTokenCreateCommand.java:247)
at org.ejbca.ui.cli.infrastructure.command.PasswordUsingCommandBase.execute(PasswordUsingCommandBase.java:201)
at org.ejbca.ui.cli.infrastructure.library.CommandLibrary$Branch.execute(CommandLibrary.java:309)
at org.ejbca.ui.cli.infrastructure.library.CommandLibrary$Branch.execute(CommandLibrary.java:320)
at org.ejbca.ui.cli.infrastructure.library.CommandLibrary.findAndExecuteCommandFromParameters(CommandLibrary.java:88)
at org.ejbca.ui.cli.EjbcaEjbCli.main(EjbcaEjbCli.java:38)
The same crypto-token configuration created via the Admin Web UI (Crypto Tokens → Create new… → Type: Azure Key Vault, Auth Type: "Application ID and Secret") succeeds and is functional at runtime (signing operations against AKV work end-to-end).
Expected Behavior
The CLI should accept this invocation and create the crypto token equivalent to the UI flow. Specifically:
--azurevaultusekeybinding / --azurevaultkeybinding should only be required when actually using KEY_BINDING auth mode.
- A new mandatory flag (or a sensible default) should populate
KEY_VAULT_AUTHENTICATION_TYPE, matching the auth modes the UI exposes.
setProperty(key, null) should never be called.
Screenshots and Logs
Full stack trace included above. The bug also reproduces on the current main branch of Keyfactor/ejbca-ce (last touch to that block: commit 9319b51178 ECA-8473 Select Key Binding in UI, which introduced the unconditional setProperty calls, no later commit fixes them).
Product Deployment
- Deployment format: container (
keyfactor/ejbca-ce:9.3.7, official Helm chart ejbca-ce 9.3.7)
- Version: 9.3.7
- Database: PostgreSQL 17 (CloudNativePG)
- Java: OpenJDK 17 (image default)
- AKV target: Premium tier vault, key type EC-HSM P-384, RBAC authorisation; App Registration with
Key Vault Crypto User on the specific key
Desktop
N/A
Describe the Bug
CryptoTokenCreateCommandthrowsNullPointerExceptionfromProperties.setPropertywhen creating an Azure Key Vault crypto token via the EJB CLI without supplying the--azurevaultusekeybindingand--azurevaultkeybindingflags. Both flags are declaredMandatoryMode.OPTIONAL, so users following the documented "App ID + Secret" auth path naturally leave them off, and the command crashes before the token is stored.Root cause: in
modules/ejbca-ejb-cli/src/org/ejbca/ui/cli/cryptotoken/CryptoTokenCreateCommand.java,lines 247–248 set these properties unconditionally with values that can be
null:Properties.setPropertyis backed byHashtable.put, which throws NPE on null keys or null values.The corresponding code path in the Admin Web UI (
CryptoTokenMBean.javalines 1304–1311) handles the same fields correctly:Two separate problems in the CLI:
setPropertyfor the two key-binding properties.KEY_VAULT_AUTHENTICATION_TYPE. At runtime,AzureCryptoToken(cryptotokens-impl-3.0.0.jar) falls back to the legacyKEY_VAULT_USE_KEY_BINDINGboolean only whenKEY_VAULT_AUTHENTICATION_TYPEis absent. The CLI therefore can't currently create a managed-identitycrypto token at all, and even an App-ID-and-Secret token relies on the legacy fallback path. The CLI needs a new flag (e.g.
--azurevaultauthtype APP_ID_AND_SECRET|KEY_BINDING|MANAGED_IDENTITY) that maps ontoKEY_VAULT_AUTHENTICATION_TYPE.To Reproduce
In an EJBCA CE 9.3.7 installation, with an Azure App Registration (client ID + secret) granted
Key Vault Crypto Useron a key in an AKV Premium vault:Observed:
The same crypto-token configuration created via the Admin Web UI (Crypto Tokens → Create new… → Type: Azure Key Vault, Auth Type: "Application ID and Secret") succeeds and is functional at runtime (signing operations against AKV work end-to-end).
Expected Behavior
The CLI should accept this invocation and create the crypto token equivalent to the UI flow. Specifically:
--azurevaultusekeybinding/--azurevaultkeybindingshould only be required when actually usingKEY_BINDINGauth mode.KEY_VAULT_AUTHENTICATION_TYPE, matching the auth modes the UI exposes.setProperty(key, null)should never be called.Screenshots and Logs
Full stack trace included above. The bug also reproduces on the current
mainbranch ofKeyfactor/ejbca-ce(last touch to that block: commit9319b51178 ECA-8473 Select Key Binding in UI, which introduced the unconditionalsetPropertycalls, no later commit fixes them).Product Deployment
keyfactor/ejbca-ce:9.3.7, official Helm chartejbca-ce 9.3.7)Key Vault Crypto Useron the specific keyDesktop
N/A