From 662aaf093b914985479fa1aef39b6438da6532bd Mon Sep 17 00:00:00 2001 From: Rashmini Date: Wed, 20 Sep 2023 11:32:26 +0530 Subject: [PATCH 1/5] Hash confirmation-code/otp in recovery --- .../impl/ValidateCodeApiServiceImpl.java | 16 +++++++-- .../recovery/IdentityRecoveryConstants.java | 1 + .../ResendConfirmationManager.java | 10 +++++- .../password/PasswordRecoveryManagerImpl.java | 25 ++++++++++++-- .../NotificationPasswordRecoveryManager.java | 34 +++++++++++++++++-- 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java index c427fb8525..c1a26e1f84 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java +++ b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java @@ -11,6 +11,8 @@ import org.wso2.carbon.identity.recovery.endpoint.ValidateCodeApiService; import org.wso2.carbon.identity.recovery.endpoint.dto.CodeValidationRequestDTO; import org.wso2.carbon.identity.recovery.password.NotificationPasswordRecoveryManager; +import org.wso2.carbon.identity.recovery.util.Utils; +import org.wso2.carbon.user.api.UserStoreException; import javax.ws.rs.core.Response; @@ -28,8 +30,18 @@ public Response validateCodePost(CodeValidationRequestDTO codeValidationRequestD try { NotificationPasswordRecoveryManager notificationPasswordRecoveryManager = RecoveryUtil .getNotificationBasedPwdRecoveryManager(); - user = notificationPasswordRecoveryManager - .getValidatedUser(codeValidationRequestDTO.getCode(), codeValidationRequestDTO.getStep()); + String code = codeValidationRequestDTO.getCode(); + try { + String hashedCode = Utils.doHash(code); + user = notificationPasswordRecoveryManager + .getValidatedUser(hashedCode, codeValidationRequestDTO.getStep()); + } catch (UserStoreException e) { + throw Utils.handleServerException( + IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); + } catch (IdentityRecoveryException e) { + user = notificationPasswordRecoveryManager + .getValidatedUser(code, codeValidationRequestDTO.getStep()); + } } catch (IdentityRecoveryClientException e) { if (LOG.isDebugEnabled()) { LOG.debug("Client Error while validating the confirmation code ", e); diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/IdentityRecoveryConstants.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/IdentityRecoveryConstants.java index 3e7c7700fb..3f438671f8 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/IdentityRecoveryConstants.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/IdentityRecoveryConstants.java @@ -304,6 +304,7 @@ public enum ErrorMessages { ERROR_CODE_ERROR_GETTING_CONNECTOR_CONFIG("20062", "Error while getting connector configurations"), ERROR_CODE_STORING_RECOVERY_FLOW_DATA("20063", "Error while storing recovery data."), ERROR_CODE_UPDATING_RECOVERY_FLOW_DATA("20064", "Error while updating recovery data."), + ERROR_CODE_NO_HASHING_ALGO_FOR_CODE("20065", "Error while hashing the code."), ERROR_CODE_ERROR_RETRIVING_CLAIM("18004", "Error when retrieving the locale claim of user '%s' of '%s' domain."), ERROR_CODE_RECOVERY_DATA_NOT_FOUND_FOR_USER("18005", "Recovery data not found."), diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/confirmation/ResendConfirmationManager.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/confirmation/ResendConfirmationManager.java index 65b185ab2c..fb551490d4 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/confirmation/ResendConfirmationManager.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/confirmation/ResendConfirmationManager.java @@ -47,6 +47,7 @@ import org.wso2.carbon.identity.recovery.store.JDBCRecoveryDataStore; import org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore; import org.wso2.carbon.identity.recovery.util.Utils; +import org.wso2.carbon.user.api.UserStoreException; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; @@ -169,6 +170,7 @@ public ResendConfirmationDTO resendConfirmation(String tenantDomain, String rese String notificationChannel = validateNotificationChannel(userRecoveryData.getRemainingSetIds()); String confirmationCode; + String hashedConfirmationCode; UserRecoveryData confirmationCodeRecoveryData = userRecoveryDataStore.loadWithoutCodeExpiryValidation(user, scenario, step); /* Checking whether the existing confirmation code can be used based on the email confirmation code tolerance @@ -180,8 +182,14 @@ public ResendConfirmationDTO resendConfirmation(String tenantDomain, String rese confirmationCode = Utils.generateSecretKey(notificationChannel, user.getTenantDomain(), recoveryScenario); confirmationCode = Utils.concatRecoveryFlowIdWithSecretKey(recoveryFlowId, notificationChannel, confirmationCode); + try { + hashedConfirmationCode = Utils.doHash(confirmationCode); + } catch (UserStoreException e) { + throw Utils.handleServerException( + IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); + } // Store new confirmation code. - addRecoveryDataObject(confirmationCode, recoveryFlowId, notificationChannel, scenario, step, user); + addRecoveryDataObject(hashedConfirmationCode, recoveryFlowId, notificationChannel, scenario, step, user); } ResendConfirmationDTO resendConfirmationDTO = new ResendConfirmationDTO(); diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java index da23fb6fc8..0e3fbfc515 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java @@ -54,6 +54,7 @@ import org.wso2.carbon.identity.user.functionality.mgt.UserFunctionalityManager; import org.wso2.carbon.identity.user.functionality.mgt.exception.UserFunctionalityManagementException; import org.wso2.carbon.identity.user.functionality.mgt.model.FunctionalityLockStatus; +import org.wso2.carbon.user.api.UserStoreException; import java.util.ArrayList; import java.util.Map; @@ -192,8 +193,18 @@ public PasswordResetCodeDTO confirm(String confirmationCode, String tenantDomain validateTenantDomain(tenantDomain); UserAccountRecoveryManager userAccountRecoveryManager = UserAccountRecoveryManager.getInstance(); // Get Recovery data. - UserRecoveryData userRecoveryData = userAccountRecoveryManager - .getUserRecoveryData(confirmationCode, RecoverySteps.UPDATE_PASSWORD); + UserRecoveryData userRecoveryData; + try { + String hashedConfirmationCode = Utils.doHash(confirmationCode); + userRecoveryData = userAccountRecoveryManager + .getUserRecoveryData(hashedConfirmationCode, RecoverySteps.UPDATE_PASSWORD); + } catch (UserStoreException e) { + throw Utils.handleServerException( + IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); + } catch (IdentityRecoveryException e) { + userRecoveryData = userAccountRecoveryManager + .getUserRecoveryData(confirmationCode, RecoverySteps.UPDATE_PASSWORD); + } if (!tenantDomain.equals(userRecoveryData.getUser().getTenantDomain())) { throw Utils.handleClientException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_USER_TENANT_DOMAIN_MISS_MATCH_WITH_CONTEXT, @@ -247,7 +258,15 @@ public PasswordResetCodeDTO confirm(String otp, String confirmationCode, String } String domainQualifiedName = IdentityUtil.addDomainToName(userRecoveryData.getUser().getUserName(), userRecoveryData.getUser().getUserStoreDomain()); - if (StringUtils.equals(code, userRecoveryData.getSecret())) { + String hashedCode; + try { + hashedCode = Utils.doHash(code); + } catch (UserStoreException e) { + throw Utils.handleServerException( + IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); + } + if (StringUtils.equals(hashedCode, userRecoveryData.getSecret()) || StringUtils.equals(code, + userRecoveryData.getSecret())) { if (log.isDebugEnabled()) { log.debug("Valid confirmation code for user: " + domainQualifiedName); } diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java index 8117a42f80..f99eba5e06 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java @@ -251,6 +251,7 @@ private UserRecoveryData generateNewConfirmationCode(User user, String notificat throws IdentityRecoveryException { String recoveryFlowId = null; + String hashedSecretKey; UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance(); UserRecoveryData userRecoveryData = userRecoveryDataStore.loadWithoutCodeExpiryValidation(user); if (userRecoveryData != null) { @@ -260,12 +261,22 @@ private UserRecoveryData generateNewConfirmationCode(User user, String notificat String secretKey = Utils.generateSecretKey(notificationChannel, user.getTenantDomain(), RecoveryScenarios.NOTIFICATION_BASED_PW_RECOVERY.name()); secretKey = Utils.concatRecoveryFlowIdWithSecretKey(recoveryFlowId, notificationChannel, secretKey); + try { + hashedSecretKey = Utils.doHash(secretKey); + } catch (UserStoreException e) { + throw Utils.handleServerException( + IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); + } UserRecoveryData recoveryDataDO = new UserRecoveryData(user, recoveryFlowId, secretKey, RecoveryScenarios.NOTIFICATION_BASED_PW_RECOVERY, RecoverySteps.UPDATE_PASSWORD); + UserRecoveryData hashedRecoveryDataDO = new UserRecoveryData(user, recoveryFlowId, hashedSecretKey, + RecoveryScenarios.NOTIFICATION_BASED_PW_RECOVERY, RecoverySteps.UPDATE_PASSWORD); + // Store the notified channel in the recovery object for future reference. recoveryDataDO.setRemainingSetIds(notificationChannel); - userRecoveryDataStore.storeConfirmationCode(recoveryDataDO); + hashedRecoveryDataDO.setRemainingSetIds(notificationChannel); + userRecoveryDataStore.storeConfirmationCode(hashedRecoveryDataDO); return recoveryDataDO; } @@ -570,7 +581,16 @@ public User updateUserPassword(String code, String password, Property[] properti UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance(); - UserRecoveryData userRecoveryData = userRecoveryDataStore.load(code); + UserRecoveryData userRecoveryData; + try { + String hashedCode = Utils.doHash(code); + userRecoveryData = userRecoveryDataStore.load(hashedCode); + } catch (UserStoreException e) { + throw Utils.handleServerException( + IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); + } catch (IdentityRecoveryException e) { + userRecoveryData = userRecoveryDataStore.load(code); + } validateCallback(properties, userRecoveryData.getUser().getTenantDomain()); publishEvent(userRecoveryData.getUser(), null, code, password, properties, IdentityEventConstants.Event.PRE_ADD_NEW_PASSWORD, userRecoveryData); @@ -670,7 +690,15 @@ public User updateUserPassword(String code, String confirmationCode, String pass validateTenantDomain(userRecoveryData.getUser()); int failedAttempts = userRecoveryData.getFailedAttempts(); - if (!StringUtils.equals(code, userRecoveryData.getSecret())) { + String hashedCode; + try { + hashedCode = Utils.doHash(code); + } catch (UserStoreException e) { + throw Utils.handleServerException( + IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); + } + if (!StringUtils.equals(hashedCode, userRecoveryData.getSecret()) && !StringUtils.equals(code, + userRecoveryData.getSecret())) { if ((failedAttempts + 1) >= Integer.parseInt(Utils.getRecoveryConfigs(IdentityRecoveryConstants. ConnectorConfig.RECOVERY_OTP_PASSWORD_MAX_FAILED_ATTEMPTS, userRecoveryData.getUser(). getTenantDomain()))) { From 7d6d0fd7b9a5e2d6e08e1be01b492b377b472666 Mon Sep 17 00:00:00 2001 From: Rashmini Date: Thu, 5 Oct 2023 10:58:29 +0530 Subject: [PATCH 2/5] Refactor code --- .../endpoint/impl/ValidateCodeApiServiceImpl.java | 14 ++------------ .../NotificationPasswordRecoveryManager.java | 11 ++++++++++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java index c1a26e1f84..a8fc3a3be8 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java +++ b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java @@ -30,18 +30,8 @@ public Response validateCodePost(CodeValidationRequestDTO codeValidationRequestD try { NotificationPasswordRecoveryManager notificationPasswordRecoveryManager = RecoveryUtil .getNotificationBasedPwdRecoveryManager(); - String code = codeValidationRequestDTO.getCode(); - try { - String hashedCode = Utils.doHash(code); - user = notificationPasswordRecoveryManager - .getValidatedUser(hashedCode, codeValidationRequestDTO.getStep()); - } catch (UserStoreException e) { - throw Utils.handleServerException( - IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); - } catch (IdentityRecoveryException e) { - user = notificationPasswordRecoveryManager - .getValidatedUser(code, codeValidationRequestDTO.getStep()); - } + user = notificationPasswordRecoveryManager + .getValidatedUser(codeValidationRequestDTO.getCode(), codeValidationRequestDTO.getStep()); } catch (IdentityRecoveryClientException e) { if (LOG.isDebugEnabled()) { LOG.debug("Client Error while validating the confirmation code ", e); diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java index f99eba5e06..b0667c33c0 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java @@ -1074,7 +1074,16 @@ public void validateConfirmationCode(String code, String recoveryStep) throws Id public User getValidatedUser(String code, String recoveryStep) throws IdentityRecoveryException { UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance(); - UserRecoveryData userRecoveryData = userRecoveryDataStore.load(code); + UserRecoveryData userRecoveryData; + try { + String hashedCode = Utils.doHash(code); + userRecoveryData = userRecoveryDataStore.load(hashedCode); + } catch (UserStoreException e) { + throw Utils.handleServerException( + IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); + } catch (IdentityRecoveryException e) { + userRecoveryData = userRecoveryDataStore.load(code); + } String contextTenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); String userTenantDomain = userRecoveryData.getUser().getTenantDomain(); if (!StringUtils.equals(contextTenantDomain, userTenantDomain)) { From 4c7abc023e115b79f158d6fca8385d01c9a4c651 Mon Sep 17 00:00:00 2001 From: Rashmini Date: Thu, 5 Oct 2023 11:00:07 +0530 Subject: [PATCH 3/5] Remove unused imports --- .../recovery/endpoint/impl/ValidateCodeApiServiceImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java index a8fc3a3be8..c427fb8525 100644 --- a/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java +++ b/components/org.wso2.carbon.identity.api.user.recovery/src/main/java/org/wso2/carbon/identity/recovery/endpoint/impl/ValidateCodeApiServiceImpl.java @@ -11,8 +11,6 @@ import org.wso2.carbon.identity.recovery.endpoint.ValidateCodeApiService; import org.wso2.carbon.identity.recovery.endpoint.dto.CodeValidationRequestDTO; import org.wso2.carbon.identity.recovery.password.NotificationPasswordRecoveryManager; -import org.wso2.carbon.identity.recovery.util.Utils; -import org.wso2.carbon.user.api.UserStoreException; import javax.ws.rs.core.Response; From c5821975215ed0a9ab572c698e20b59881a214e9 Mon Sep 17 00:00:00 2001 From: Rashmini Date: Thu, 5 Oct 2023 12:02:33 +0530 Subject: [PATCH 4/5] Introduce a separate method for hashing --- .../ResendConfirmationManager.java | 6 +++--- .../password/PasswordRecoveryManagerImpl.java | 10 ++++----- .../NotificationPasswordRecoveryManager.java | 21 ++++++++++--------- .../carbon/identity/recovery/util/Utils.java | 13 ++++++++++++ 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/confirmation/ResendConfirmationManager.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/confirmation/ResendConfirmationManager.java index fb551490d4..248746a5d4 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/confirmation/ResendConfirmationManager.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/confirmation/ResendConfirmationManager.java @@ -47,10 +47,10 @@ import org.wso2.carbon.identity.recovery.store.JDBCRecoveryDataStore; import org.wso2.carbon.identity.recovery.store.UserRecoveryDataStore; import org.wso2.carbon.identity.recovery.util.Utils; -import org.wso2.carbon.user.api.UserStoreException; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; +import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.UUID; @@ -183,8 +183,8 @@ public ResendConfirmationDTO resendConfirmation(String tenantDomain, String rese confirmationCode = Utils.concatRecoveryFlowIdWithSecretKey(recoveryFlowId, notificationChannel, confirmationCode); try { - hashedConfirmationCode = Utils.doHash(confirmationCode); - } catch (UserStoreException e) { + hashedConfirmationCode = Utils.hashCode(confirmationCode); + } catch (NoSuchAlgorithmException e) { throw Utils.handleServerException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); } diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java index 0e3fbfc515..203d76d89c 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/internal/service/impl/password/PasswordRecoveryManagerImpl.java @@ -54,8 +54,8 @@ import org.wso2.carbon.identity.user.functionality.mgt.UserFunctionalityManager; import org.wso2.carbon.identity.user.functionality.mgt.exception.UserFunctionalityManagementException; import org.wso2.carbon.identity.user.functionality.mgt.model.FunctionalityLockStatus; -import org.wso2.carbon.user.api.UserStoreException; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Map; import java.util.UUID; @@ -195,10 +195,10 @@ public PasswordResetCodeDTO confirm(String confirmationCode, String tenantDomain // Get Recovery data. UserRecoveryData userRecoveryData; try { - String hashedConfirmationCode = Utils.doHash(confirmationCode); + String hashedConfirmationCode = Utils.hashCode(confirmationCode); userRecoveryData = userAccountRecoveryManager .getUserRecoveryData(hashedConfirmationCode, RecoverySteps.UPDATE_PASSWORD); - } catch (UserStoreException e) { + } catch (NoSuchAlgorithmException e) { throw Utils.handleServerException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); } catch (IdentityRecoveryException e) { @@ -260,8 +260,8 @@ public PasswordResetCodeDTO confirm(String otp, String confirmationCode, String userRecoveryData.getUser().getUserStoreDomain()); String hashedCode; try { - hashedCode = Utils.doHash(code); - } catch (UserStoreException e) { + hashedCode = Utils.hashCode(code); + } catch (NoSuchAlgorithmException e) { throw Utils.handleServerException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); } diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java index b0667c33c0..196811355a 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/password/NotificationPasswordRecoveryManager.java @@ -65,6 +65,7 @@ import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; +import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; @@ -262,8 +263,8 @@ private UserRecoveryData generateNewConfirmationCode(User user, String notificat RecoveryScenarios.NOTIFICATION_BASED_PW_RECOVERY.name()); secretKey = Utils.concatRecoveryFlowIdWithSecretKey(recoveryFlowId, notificationChannel, secretKey); try { - hashedSecretKey = Utils.doHash(secretKey); - } catch (UserStoreException e) { + hashedSecretKey = Utils.hashCode(secretKey); + } catch (NoSuchAlgorithmException e) { throw Utils.handleServerException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); } @@ -583,9 +584,9 @@ public User updateUserPassword(String code, String password, Property[] properti UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance(); UserRecoveryData userRecoveryData; try { - String hashedCode = Utils.doHash(code); + String hashedCode = Utils.hashCode(code); userRecoveryData = userRecoveryDataStore.load(hashedCode); - } catch (UserStoreException e) { + } catch (NoSuchAlgorithmException e) { throw Utils.handleServerException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); } catch (IdentityRecoveryException e) { @@ -692,13 +693,13 @@ public User updateUserPassword(String code, String confirmationCode, String pass String hashedCode; try { - hashedCode = Utils.doHash(code); - } catch (UserStoreException e) { + hashedCode = Utils.hashCode(code); + } catch (NoSuchAlgorithmException e) { throw Utils.handleServerException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); } - if (!StringUtils.equals(hashedCode, userRecoveryData.getSecret()) && !StringUtils.equals(code, - userRecoveryData.getSecret())) { + if (!(StringUtils.equals(hashedCode, userRecoveryData.getSecret()) || StringUtils.equals(code, + userRecoveryData.getSecret()))) { if ((failedAttempts + 1) >= Integer.parseInt(Utils.getRecoveryConfigs(IdentityRecoveryConstants. ConnectorConfig.RECOVERY_OTP_PASSWORD_MAX_FAILED_ATTEMPTS, userRecoveryData.getUser(). getTenantDomain()))) { @@ -1076,9 +1077,9 @@ public User getValidatedUser(String code, String recoveryStep) throws IdentityRe UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance(); UserRecoveryData userRecoveryData; try { - String hashedCode = Utils.doHash(code); + String hashedCode = Utils.hashCode(code); userRecoveryData = userRecoveryDataStore.load(hashedCode); - } catch (UserStoreException e) { + } catch (NoSuchAlgorithmException e) { throw Utils.handleServerException( IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_NO_HASHING_ALGO_FOR_CODE, null); } catch (IdentityRecoveryException e) { diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java index ac4d242ab2..254895a9c4 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java @@ -427,6 +427,19 @@ public static String doHash(String value) throws UserStoreException { } } + /** + * @param value Value to be hashed + * @return Hashed value + * @throws NoSuchAlgorithmException If the algorithm is not found. + */ + public static String hashCode(String value) throws NoSuchAlgorithmException { + + String digsestFunction = "SHA-256"; + MessageDigest dgst = MessageDigest.getInstance(digsestFunction); + byte[] byteValue = dgst.digest(value.getBytes(StandardCharsets.UTF_8)); + return Base64.encode(byteValue); + } + /** * Set claim to user store manager * From f742d185c13617f54d6f9213f154c2acad87ac3e Mon Sep 17 00:00:00 2001 From: Rashmini Date: Thu, 5 Oct 2023 13:39:05 +0530 Subject: [PATCH 5/5] Fix comments --- .../java/org/wso2/carbon/identity/recovery/util/Utils.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java index 254895a9c4..36692ba562 100644 --- a/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java +++ b/components/org.wso2.carbon.identity.recovery/src/main/java/org/wso2/carbon/identity/recovery/util/Utils.java @@ -414,13 +414,11 @@ public static IdentityRecoveryClientException handleClientException(String error * @return * @throws UserStoreException */ + @Deprecated public static String doHash(String value) throws UserStoreException { try { - String digsestFunction = "SHA-256"; - MessageDigest dgst = MessageDigest.getInstance(digsestFunction); - byte[] byteValue = dgst.digest(value.getBytes(StandardCharsets.UTF_8)); - return Base64.encode(byteValue); + return hashCode(value); } catch (NoSuchAlgorithmException e) { log.error(e.getMessage(), e); throw new UserStoreException(e.getMessage(), e);