From 97d32688bc2b83590053980fea95679ef33fbfcb Mon Sep 17 00:00:00 2001 From: RiccardoGiuliani Date: Fri, 16 Feb 2024 15:05:13 +0100 Subject: [PATCH] Modified string to byte[] --- .../idpay/azurekeyvault/util/EncryptUtil.java | 15 +++- .../mil/idpay/bean/AuthCodeBlockData.java | 4 +- .../idpay/service/TransactionsService.java | 8 +- .../TransactionResourceAuthorizationTest.java | 90 +++++++++++++++++++ .../mil/idpay/util/TransactionsTestData.java | 4 +- 5 files changed, 108 insertions(+), 13 deletions(-) diff --git a/src/main/java/it/pagopa/swclient/mil/idpay/azurekeyvault/util/EncryptUtil.java b/src/main/java/it/pagopa/swclient/mil/idpay/azurekeyvault/util/EncryptUtil.java index 8c28e8e..fb34c02 100644 --- a/src/main/java/it/pagopa/swclient/mil/idpay/azurekeyvault/util/EncryptUtil.java +++ b/src/main/java/it/pagopa/swclient/mil/idpay/azurekeyvault/util/EncryptUtil.java @@ -8,7 +8,10 @@ import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.math.BigInteger; -import java.security.*; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPublicKeySpec; import java.util.Base64; @@ -21,8 +24,8 @@ public String encryptSessionKeyForIdpay(PublicKeyIDPay publicKeyIDPay, String se String exponentBase64 = publicKeyIDPay.getE(); // Decode Base64 values in byte - byte[] modulusBytes = Base64.getUrlDecoder().decode(modulusBase64); - byte[] exponentBytes = Base64.getUrlDecoder().decode(exponentBase64); + byte[] modulusBytes = decodeBase64UrlOrBase64(modulusBase64); + byte[] exponentBytes = decodeBase64UrlOrBase64(exponentBase64); // Create specific RSA public key RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec( @@ -37,10 +40,14 @@ public String encryptSessionKeyForIdpay(PublicKeyIDPay publicKeyIDPay, String se Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey); - byte[] sessionKeyBytes = Base64.getUrlDecoder().decode(sessionKey); + byte[] sessionKeyBytes = decodeBase64UrlOrBase64(sessionKey); byte[] encryptedSessionKeyBytes = cipher.doFinal(sessionKeyBytes); // encryptedSessionKeyBytes contains encrypted session key return Base64.getEncoder().encodeToString(encryptedSessionKeyBytes); } + + private byte[] decodeBase64UrlOrBase64(String base64) { + return (base64.contains("-") || base64.contains("_") ? Base64.getUrlDecoder() : Base64.getDecoder()).decode(base64); + } } diff --git a/src/main/java/it/pagopa/swclient/mil/idpay/bean/AuthCodeBlockData.java b/src/main/java/it/pagopa/swclient/mil/idpay/bean/AuthCodeBlockData.java index 2fa4785..d60ec81 100644 --- a/src/main/java/it/pagopa/swclient/mil/idpay/bean/AuthCodeBlockData.java +++ b/src/main/java/it/pagopa/swclient/mil/idpay/bean/AuthCodeBlockData.java @@ -19,10 +19,10 @@ public class AuthCodeBlockData { @NotNull(message = "[" + ErrorCode.ERROR_ENCSESSIONKEY_MUST_NOT_BE_NULL + "] encSessionKey must not be null") @Size(min = 256, max = 2048, message = "[" + ErrorCode.ERROR_ENCSESSIONKEY_MUST_BE_BETWEEN + "] encSessionKey must be between than {min} and {max}") - private String encSessionKey; + private byte[] encSessionKey; @NotNull(message = "[" + ErrorCode.ERROR_AUTHCODEBLOCK_MUST_NOT_BE_NULL + "] authCodeBlock must not be null") @Size(min = 16, max = 16, message = "[" + ErrorCode.ERROR_AUTHCODEBLOCK_MUST_BE_BETWEEN + "] authCodeBlock must be between than {min} and {max}") - private String authCodeBlock; + private byte[] authCodeBlock; } diff --git a/src/main/java/it/pagopa/swclient/mil/idpay/service/TransactionsService.java b/src/main/java/it/pagopa/swclient/mil/idpay/service/TransactionsService.java index e014f7a..edb6d9a 100644 --- a/src/main/java/it/pagopa/swclient/mil/idpay/service/TransactionsService.java +++ b/src/main/java/it/pagopa/swclient/mil/idpay/service/TransactionsService.java @@ -591,7 +591,7 @@ private Uni unwrapKey(AuthorizeTransaction authorizeTransacti UnwrapKeyRequest unwrapKeyRequest = UnwrapKeyRequest .builder() .alg("RSA-OAEP-256") - .value(authorizeTransaction.getAuthCodeBlockData().getEncSessionKey()) + .value(Base64.getEncoder().encodeToString(authorizeTransaction.getAuthCodeBlockData().getEncSessionKey())) .build(); return azureKeyVaultClient.unwrapKey(BEARER + token.getToken(), authorizeTransaction.getAuthCodeBlockData().getKid(), unwrapKeyRequest) @@ -889,11 +889,9 @@ private InternalServerErrorException certificateException(Throwable exception, S .build()); } - private static String base64ToHex(String base64String) { - byte[] decodedBytes = Base64.getDecoder().decode(base64String); - + private static String base64ToHex(byte[] authCodeBlock) { StringBuilder hexStringBuilder = new StringBuilder(); - for (byte b : decodedBytes) { + for (byte b : authCodeBlock) { hexStringBuilder.append(String.format("%02X", b & 0xFF)); } diff --git a/src/test/java/it/pagopa/swclient/mil/idpay/TransactionResourceAuthorizationTest.java b/src/test/java/it/pagopa/swclient/mil/idpay/TransactionResourceAuthorizationTest.java index 6430d64..845e3ff 100644 --- a/src/test/java/it/pagopa/swclient/mil/idpay/TransactionResourceAuthorizationTest.java +++ b/src/test/java/it/pagopa/swclient/mil/idpay/TransactionResourceAuthorizationTest.java @@ -671,4 +671,94 @@ void authorizeTransactionTest_KOCertAndKO500() { Assertions.assertEquals(1, response.jsonPath().getList("errors").size()); Assertions.assertEquals(1, response.jsonPath().getList("descriptions").size()); } + + @Test + @TestSecurity(user = "testUser", roles = {"PayWithIDPay"}) + void authorizeTransactionTest_OKAuthorizeModulusBase64Url() { + + Mockito.when(idpayTransactionRepository.findById(Mockito.any(String.class))).thenReturn(Uni.createFrom().item(idpayTransactionEntity)); + + Mockito.when(azureADRestClient.getAccessToken(Mockito.any(String.class), Mockito.any(String.class))) + .thenReturn((Uni.createFrom().item(azureAdAccessToken))); + + Mockito.when(azureKeyVaultClient.getCertificate(Mockito.any(String.class), Mockito.any(String.class))) + .thenReturn(Uni.createFrom().item(certificateBundle)); + + Mockito.when(azureKeyVaultClient.getSecret(Mockito.any(String.class), Mockito.any(String.class))) + .thenReturn(Uni.createFrom().item(secretBundle)); + + Mockito.when(azureKeyVaultClient.unwrapKey(Mockito.any(String.class), Mockito.any(String.class), Mockito.any(UnwrapKeyRequest.class))) + .thenReturn(Uni.createFrom().item(unwrapKeyResponse)); + + publicKeyIDPay.setE("----------"); + + Mockito.when(idPayRestService.retrieveIdpayPublicKey(Mockito.any(String.class))) + .thenReturn(Uni.createFrom().item(publicKeyIDPay)); + + Mockito.when(idPayRestService.authorize(Mockito.any(String.class), Mockito.any(String.class), Mockito.any(String.class), Mockito.any(PinBlockDTO.class))) + .thenReturn(Uni.createFrom().item(authTransactionResponse)); + + + Response response = given() + .contentType(ContentType.JSON) + .headers(validMilHeaders) + .and() + .body(authorizeTransaction) + .pathParam("milTransactionId", transactionId) + .when() + .post("/{milTransactionId}/authorize") + .then() + .extract() + .response(); + + publicKeyIDPay = TransactionsTestData.getPublicKeyIdPay(); + idpayTransactionEntity = TransactionsTestData.getTransactionEntity(validMilHeaders, createTransactionRequest, transactionResponse); + + Assertions.assertEquals(200, response.statusCode()); + } + + @Test + @TestSecurity(user = "testUser", roles = {"PayWithIDPay"}) + void authorizeTransactionTest_OKAuthorizeModulusBase64Url2() { + + Mockito.when(idpayTransactionRepository.findById(Mockito.any(String.class))).thenReturn(Uni.createFrom().item(idpayTransactionEntity)); + + Mockito.when(azureADRestClient.getAccessToken(Mockito.any(String.class), Mockito.any(String.class))) + .thenReturn((Uni.createFrom().item(azureAdAccessToken))); + + Mockito.when(azureKeyVaultClient.getCertificate(Mockito.any(String.class), Mockito.any(String.class))) + .thenReturn(Uni.createFrom().item(certificateBundle)); + + Mockito.when(azureKeyVaultClient.getSecret(Mockito.any(String.class), Mockito.any(String.class))) + .thenReturn(Uni.createFrom().item(secretBundle)); + + Mockito.when(azureKeyVaultClient.unwrapKey(Mockito.any(String.class), Mockito.any(String.class), Mockito.any(UnwrapKeyRequest.class))) + .thenReturn(Uni.createFrom().item(unwrapKeyResponse)); + + publicKeyIDPay.setE("__________"); + + Mockito.when(idPayRestService.retrieveIdpayPublicKey(Mockito.any(String.class))) + .thenReturn(Uni.createFrom().item(publicKeyIDPay)); + + Mockito.when(idPayRestService.authorize(Mockito.any(String.class), Mockito.any(String.class), Mockito.any(String.class), Mockito.any(PinBlockDTO.class))) + .thenReturn(Uni.createFrom().item(authTransactionResponse)); + + + Response response = given() + .contentType(ContentType.JSON) + .headers(validMilHeaders) + .and() + .body(authorizeTransaction) + .pathParam("milTransactionId", transactionId) + .when() + .post("/{milTransactionId}/authorize") + .then() + .extract() + .response(); + + publicKeyIDPay = TransactionsTestData.getPublicKeyIdPay(); + idpayTransactionEntity = TransactionsTestData.getTransactionEntity(validMilHeaders, createTransactionRequest, transactionResponse); + + Assertions.assertEquals(200, response.statusCode()); + } } diff --git a/src/test/java/it/pagopa/swclient/mil/idpay/util/TransactionsTestData.java b/src/test/java/it/pagopa/swclient/mil/idpay/util/TransactionsTestData.java index 9624d98..6541d0f 100644 --- a/src/test/java/it/pagopa/swclient/mil/idpay/util/TransactionsTestData.java +++ b/src/test/java/it/pagopa/swclient/mil/idpay/util/TransactionsTestData.java @@ -248,9 +248,9 @@ public static AuthorizeTransaction getAuthorizeTransaction() { AuthorizeTransaction authorizeTransaction = new AuthorizeTransaction(); AuthCodeBlockData authCodeBlockData = new AuthCodeBlockData(); - authCodeBlockData.setAuthCodeBlock("MDAwMTAyMDMwNDA1MDYwNzA4MDkwQTBCMEMwRDBFMEY="); + authCodeBlockData.setAuthCodeBlock("MDAwMTAyMDMwNDA1MDYwNzA4MDkwQTBCMEMwRDBFMEY=".getBytes()); authCodeBlockData.setKid(vaultUrl + "/keys/0709643f49394529b92c19a68c8e184a/6581c704deda4979943c3b34468df7c2"); - authCodeBlockData.setEncSessionKey("et2j4kthRmeuc5uzCLi9dE9LeQKCsqbTNxNDwrJ-mBFA4UZQaXS1hdRw6ygXoH6Ra1uciDMDHpbg7DJoYfis_foMzk3gIQxrGkmcbsPkC2ieklIpOf021smzd_pSFJ580XQzwOJCli762aRByuNQAVFismcRhkSCad8fcRe7TgevephXcrbrjr25eCRgvmACESfrydnopO5g6yIkINpzuK9wP4ljDZTO90hP-_uRrfrgjwdxa6vv-qilYqvC4RPL7HR7eEbxkHFvsri7F7J9QDp5GsAJK1Bh4EdaLyl6MwYW1sEFnpQ-27_xtvFbwFANdB70cxsosvNsRueMjh9s-2rhgPZIT_YyHn3s394OOOKql5Umamn6pvcejPgXnXY0nRmSHCDoSUzNzEnQb1sxhuDpvQLQpWsKD3DESIjaDBq7sSvpBsoOg1ybnMccWiaIIRXCpYJU8aPhrkVTR-AczxwfwKtcCipLk3CiEjv6iu6PxfO62BGGRSUpe_m_HfU02DmT4qa6wUHbg0Sy3NBwBNvBVOVVIfwzmxZcQ6D5MhJaPSlfzcp4iTLk2a3eQU0bvJ3WsTdKhwuK6VgB2IV99i4ZX_bnxBaqKOzc1I3StTPGVAVCMjsTXGy0OyHDOtJv5A4N18r8rHyIVfzOuBEDa05_cp3ceHtrE8Dl5KzjFbY"); + authCodeBlockData.setEncSessionKey("et2j4kthRmeuc5uzCLi9dE9LeQKCsqbTNxNDwrJ-mBFA4UZQaXS1hdRw6ygXoH6Ra1uciDMDHpbg7DJoYfis_foMzk3gIQxrGkmcbsPkC2ieklIpOf021smzd_pSFJ580XQzwOJCli762aRByuNQAVFismcRhkSCad8fcRe7TgevephXcrbrjr25eCRgvmACESfrydnopO5g6yIkINpzuK9wP4ljDZTO90hP-_uRrfrgjwdxa6vv-qilYqvC4RPL7HR7eEbxkHFvsri7F7J9QDp5GsAJK1Bh4EdaLyl6MwYW1sEFnpQ-27_xtvFbwFANdB70cxsosvNsRueMjh9s-2rhgPZIT_YyHn3s394OOOKql5Umamn6pvcejPgXnXY0nRmSHCDoSUzNzEnQb1sxhuDpvQLQpWsKD3DESIjaDBq7sSvpBsoOg1ybnMccWiaIIRXCpYJU8aPhrkVTR-AczxwfwKtcCipLk3CiEjv6iu6PxfO62BGGRSUpe_m_HfU02DmT4qa6wUHbg0Sy3NBwBNvBVOVVIfwzmxZcQ6D5MhJaPSlfzcp4iTLk2a3eQU0bvJ3WsTdKhwuK6VgB2IV99i4ZX_bnxBaqKOzc1I3StTPGVAVCMjsTXGy0OyHDOtJv5A4N18r8rHyIVfzOuBEDa05_cp3ceHtrE8Dl5KzjFbY".getBytes()); authorizeTransaction.setAuthCodeBlockData(authCodeBlockData);