From eec03873814cedbb27e69169da9c019c73c33f9a Mon Sep 17 00:00:00 2001 From: trialblazerseee <84778104+trialblazerseee@users.noreply.github.com> Date: Sun, 4 May 2025 08:50:05 +0530 Subject: [PATCH] MOSIP - 41382 - Facing slowness issue in Keymanager decrypt request - Cache Fixing has been made in safenety & nchiper class --- .../hsm/impl/NCipherHSMKeyStoreImpl.java | 80 +++++++++++++++++- .../hsm/impl/SafenetLunaKeyStoreImpl.java | 81 ++++++++++++++++++- 2 files changed, 156 insertions(+), 5 deletions(-) diff --git a/hsm-keystore-impl/ncipher-hsm-impl/src/main/java/io/mosip/keymanager/hsm/impl/NCipherHSMKeyStoreImpl.java b/hsm-keystore-impl/ncipher-hsm-impl/src/main/java/io/mosip/keymanager/hsm/impl/NCipherHSMKeyStoreImpl.java index d4e9575..c4b983c 100644 --- a/hsm-keystore-impl/ncipher-hsm-impl/src/main/java/io/mosip/keymanager/hsm/impl/NCipherHSMKeyStoreImpl.java +++ b/hsm-keystore-impl/ncipher-hsm-impl/src/main/java/io/mosip/keymanager/hsm/impl/NCipherHSMKeyStoreImpl.java @@ -115,6 +115,12 @@ public class NCipherHSMKeyStoreImpl implements io.mosip.kernel.core.keymanager.s */ private String signAlgorithm; + private boolean enableKeyReferenceCache; + + private Map privateKeyReferenceCache; + + private Map secretKeyReferenceCache; + /** * The Keystore instance */ @@ -134,12 +140,14 @@ public NCipherHSMKeyStoreImpl(Map params) throws Exception { this.asymmetricKeyAlgorithm = params.get(KeymanagerConstant.ASYM_KEY_ALGORITHM); this.asymmetricKeyLength = Integer.valueOf(params.get(KeymanagerConstant.ASYM_KEY_SIZE)); this.signAlgorithm = params.get(KeymanagerConstant.CERT_SIGN_ALGORITHM); + this.enableKeyReferenceCache = Boolean.parseBoolean(params.get(KeymanagerConstant.FLAG_KEY_REF_CACHE)); initKeystore(); LOGGER.info("NCipher-sessionId", "nFastHSM", "id", "HSM Keystore initalized." ); } private void initKeystore() { + initKeyReferenceCache(); nCipherProvider = new nCipherKM(); addProvider(); cardProtectionPwd = getKeystorePwd(); @@ -148,6 +156,13 @@ private void initKeystore() { this.keyStore = getKeystoreInstance(); } + private void initKeyReferenceCache() { + if(!enableKeyReferenceCache) + return; + this.privateKeyReferenceCache = new ConcurrentHashMap<>(); + this.secretKeyReferenceCache = new ConcurrentHashMap<>(); + } + private char[] getKeystorePwd() { if (keystorePass.trim().length() == 0) { throw new KeystoreProcessingException(KeymanagerErrorCode.NOT_VALID_STORE_PASSWORD.getErrorCode(), @@ -230,11 +245,19 @@ public Key getKey(String alias) { @SuppressWarnings("findsecbugs:HARD_CODE_PASSWORD") @Override public PrivateKeyEntry getAsymmetricKey(String alias) { + PrivateKeyEntry privateKeyEntry = getPrivateKeyEntryFromCache(alias); + if(privateKeyEntry != null) + return privateKeyEntry; + try { if (keyStore.entryInstanceOf(alias, PrivateKeyEntry.class)) { LOGGER.debug("sessionId", "KeyStoreImpl", "getAsymmetricKey", "alias is instanceof privatekeyentry"); ProtectionParameter password = getPasswordProtection(); - return (PrivateKeyEntry) keyStore.getEntry(alias, password); + privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry(alias, password); + if (privateKeyEntry != null) { + LOGGER.debug("sessionId", "KeyStoreImpl", "getAsymmetricKey", "privateKeyEntry is not null"); + break; + } } else { throw new NoSuchSecurityProviderException(KeymanagerErrorCode.NO_SUCH_ALIAS.getErrorCode(), KeymanagerErrorCode.NO_SUCH_ALIAS.getErrorMessage() + alias); @@ -243,6 +266,14 @@ public PrivateKeyEntry getAsymmetricKey(String alias) { throw new KeystoreProcessingException(KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorCode(), KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + e.getMessage(), e); } + + if (Objects.isNull(privateKeyEntry)) { + LOGGER.debug("sessionId", "KeyStoreImpl", "getAsymmetricKey", "privateKeyEntry is null"); + throw new KeystoreProcessingException(KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorCode(), + KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + expMessage, exp); + } + addPrivateKeyEntryToCache(alias, privateKeyEntry); + return privateKeyEntry; } @Override @@ -268,11 +299,19 @@ public X509Certificate getCertificate(String alias) { @SuppressWarnings("findsecbugs:HARD_CODE_PASSWORD") @Override public SecretKey getSymmetricKey(String alias) { + SecretKey secretKey = getSecretKeyFromCache(alias); + if(secretKey != null) + return secretKey; + try { if (keyStore.entryInstanceOf(alias, SecretKeyEntry.class)) { ProtectionParameter password = getPasswordProtection(); SecretKeyEntry retrivedSecret = (SecretKeyEntry) keyStore.getEntry(alias, password); - return retrivedSecret.getSecretKey(); + secretKey = retrivedSecret.getSecretKey(); + if (secretKey != null) { + LOGGER.debug("sessionId", "KeyStoreImpl", "getSymmetricKey", "secretKey is not null"); + break; + } } else { throw new NoSuchSecurityProviderException(KeymanagerErrorCode.NO_SUCH_ALIAS.getErrorCode(), KeymanagerErrorCode.NO_SUCH_ALIAS.getErrorMessage() + alias); @@ -281,6 +320,14 @@ public SecretKey getSymmetricKey(String alias) { throw new KeystoreProcessingException(KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorCode(), KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + e.getMessage(), e); } + + if (Objects.isNull(secretKey)) { + LOGGER.debug("sessionId", "KeyStoreImpl", "getSymmetricKey", "secretKey is null"); + throw new KeystoreProcessingException(KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorCode(), + KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + expMessage, exp); + } + addSecretKeyToCache(alias, secretKey); + return secretKey; } @Override @@ -409,4 +456,33 @@ private void persistKeyInHSM(){ KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + e.getMessage(), e); } } + + private void addPrivateKeyEntryToCache(String alias, PrivateKeyEntry privateKeyEntry) { + if(!enableKeyReferenceCache) + return; + LOGGER.debug("sessionId", "KeyStoreImpl", "addPrivateKeyEntryToCache", + "Adding private key reference to map for alias " + alias); + this.privateKeyReferenceCache.put(alias, privateKeyEntry); + } + + private PrivateKeyEntry getPrivateKeyEntryFromCache(String alias) { + if(!enableKeyReferenceCache) + return null; + return this.privateKeyReferenceCache.get(alias); + } + + + private void addSecretKeyToCache(String alias, SecretKey secretKey) { + if(!enableKeyReferenceCache) + return; + LOGGER.debug("sessionId", "KeyStoreImpl", "addSecretKeyToCache", + "Adding secretKey reference to map for alias " + alias); + this.secretKeyReferenceCache.put(alias, secretKey); + } + + private SecretKey getSecretKeyFromCache(String alias) { + if(!enableKeyReferenceCache) + return null; + return this.secretKeyReferenceCache.get(alias); + } } diff --git a/hsm-keystore-impl/safenet-luna-impl/src/main/java/io/mosip/keymanager/hsm/impl/SafenetLunaKeyStoreImpl.java b/hsm-keystore-impl/safenet-luna-impl/src/main/java/io/mosip/keymanager/hsm/impl/SafenetLunaKeyStoreImpl.java index 5432b4f..88fcade 100644 --- a/hsm-keystore-impl/safenet-luna-impl/src/main/java/io/mosip/keymanager/hsm/impl/SafenetLunaKeyStoreImpl.java +++ b/hsm-keystore-impl/safenet-luna-impl/src/main/java/io/mosip/keymanager/hsm/impl/SafenetLunaKeyStoreImpl.java @@ -100,6 +100,12 @@ public class SafenetLunaKeyStoreImpl implements io.mosip.kernel.core.keymanager. */ private String signAlgorithm; + private boolean enableKeyReferenceCache; + + private Map privateKeyReferenceCache; + + private Map secretKeyReferenceCache; + /** * The Keystore instance */ @@ -119,16 +125,26 @@ public SafenetLunaKeyStoreImpl(Map params) throws Exception { this.asymmetricKeyAlgorithm = params.get(KeymanagerConstant.ASYM_KEY_ALGORITHM); this.asymmetricKeyLength = Integer.valueOf(params.get(KeymanagerConstant.ASYM_KEY_SIZE)); this.signAlgorithm = params.get(KeymanagerConstant.CERT_SIGN_ALGORITHM); + this.enableKeyReferenceCache = Boolean.parseBoolean(params.get(KeymanagerConstant.FLAG_KEY_REF_CACHE)); + initKeystore(); } private void initKeystore() { + initKeyReferenceCache(); lunaProvider = new LunaProvider(); addProvider(); partitionPwdCharArr = getKeystorePwd(); this.keyStore = getKeystoreInstance(); } + private void initKeyReferenceCache() { + if(!enableKeyReferenceCache) + return; + this.privateKeyReferenceCache = new ConcurrentHashMap<>(); + this.secretKeyReferenceCache = new ConcurrentHashMap<>(); + } + private char[] getKeystorePwd() { if (keystorePass.trim().length() == 0) { throw new KeystoreProcessingException(KeymanagerErrorCode.NOT_VALID_STORE_PASSWORD.getErrorCode(), @@ -189,12 +205,19 @@ public Key getKey(String alias) { @SuppressWarnings("findsecbugs:HARD_CODE_PASSWORD") @Override public PrivateKeyEntry getAsymmetricKey(String alias) { + PrivateKeyEntry privateKeyEntry = getPrivateKeyEntryFromCache(alias); + if(privateKeyEntry != null) + return privateKeyEntry; try { if (keyStore.entryInstanceOf(alias, PrivateKeyEntry.class)) { LOGGER.debug("sessionId", "KeyStoreImpl", "getAsymmetricKey", "alias is instanceof keystore"); ProtectionParameter password = getPasswordProtection(); - return (PrivateKeyEntry) keyStore.getEntry(alias, password); + privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry(alias, password); + if (privateKeyEntry != null) { + LOGGER.debug("sessionId", "KeyStoreImpl", "getAsymmetricKey", "privateKeyEntry is not null"); + break; + } } else { throw new NoSuchSecurityProviderException(KeymanagerErrorCode.NO_SUCH_ALIAS.getErrorCode(), KeymanagerErrorCode.NO_SUCH_ALIAS.getErrorMessage() + alias); @@ -203,6 +226,14 @@ public PrivateKeyEntry getAsymmetricKey(String alias) { throw new KeystoreProcessingException(KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorCode(), KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + e.getMessage(), e); } + + if (Objects.isNull(privateKeyEntry)) { + LOGGER.debug("sessionId", "KeyStoreImpl", "getAsymmetricKey", "privateKeyEntry is null"); + throw new KeystoreProcessingException(KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorCode(), + KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + expMessage, exp); + } + addPrivateKeyEntryToCache(alias, privateKeyEntry); + return privateKeyEntry; } @Override @@ -228,12 +259,19 @@ public X509Certificate getCertificate(String alias) { @SuppressWarnings("findsecbugs:HARD_CODE_PASSWORD") @Override public SecretKey getSymmetricKey(String alias) { - + SecretKey secretKey = getSecretKeyFromCache(alias); + if(secretKey != null) + return secretKey; + try { if (keyStore.entryInstanceOf(alias, SecretKeyEntry.class)) { ProtectionParameter password = getPasswordProtection(); SecretKeyEntry retrivedSecret = (SecretKeyEntry) keyStore.getEntry(alias, password); - return retrivedSecret.getSecretKey(); + secretKey = retrivedSecret.getSecretKey(); + if (secretKey != null) { + LOGGER.debug("sessionId", "KeyStoreImpl", "getSymmetricKey", "secretKey is not null"); + break; + } } else { throw new NoSuchSecurityProviderException(KeymanagerErrorCode.NO_SUCH_ALIAS.getErrorCode(), KeymanagerErrorCode.NO_SUCH_ALIAS.getErrorMessage() + alias); @@ -242,6 +280,14 @@ public SecretKey getSymmetricKey(String alias) { throw new KeystoreProcessingException(KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorCode(), KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + e.getMessage(), e); } + + if (Objects.isNull(secretKey)) { + LOGGER.debug("sessionId", "KeyStoreImpl", "getSymmetricKey", "secretKey is null"); + throw new KeystoreProcessingException(KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorCode(), + KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + expMessage, exp); + } + addSecretKeyToCache(alias, secretKey); + return secretKey; } @Override @@ -370,4 +416,33 @@ private void persistKeyInHSM(){ KeymanagerErrorCode.KEYSTORE_PROCESSING_ERROR.getErrorMessage() + e.getMessage(), e); } } + + private void addPrivateKeyEntryToCache(String alias, PrivateKeyEntry privateKeyEntry) { + if(!enableKeyReferenceCache) + return; + LOGGER.debug("sessionId", "KeyStoreImpl", "addPrivateKeyEntryToCache", + "Adding private key reference to map for alias " + alias); + this.privateKeyReferenceCache.put(alias, privateKeyEntry); + } + + private PrivateKeyEntry getPrivateKeyEntryFromCache(String alias) { + if(!enableKeyReferenceCache) + return null; + return this.privateKeyReferenceCache.get(alias); + } + + + private void addSecretKeyToCache(String alias, SecretKey secretKey) { + if(!enableKeyReferenceCache) + return; + LOGGER.debug("sessionId", "KeyStoreImpl", "addSecretKeyToCache", + "Adding secretKey reference to map for alias " + alias); + this.secretKeyReferenceCache.put(alias, secretKey); + } + + private SecretKey getSecretKeyFromCache(String alias) { + if(!enableKeyReferenceCache) + return null; + return this.secretKeyReferenceCache.get(alias); + } }