From 37f738b1439e242027503e678e0acda82c29db31 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 20 Dec 2022 15:17:31 +0100 Subject: [PATCH 01/53] Fix #269: Set develop version to 1.5.0-SNAPSHOT --- pom.xml | 4 +++- powerauth-java-cmd-lib/pom.xml | 2 +- powerauth-java-cmd/pom.xml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 14f46cef..5c9d6e70 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ io.getlime.security powerauth-cmd-parent - 1.4.0 + ${revision} pom 2016 @@ -72,6 +72,8 @@ + 1.5.0-SNAPSHOT + UTF-8 1.8 1.8 diff --git a/powerauth-java-cmd-lib/pom.xml b/powerauth-java-cmd-lib/pom.xml index 1c3fbd2b..db4fad90 100644 --- a/powerauth-java-cmd-lib/pom.xml +++ b/powerauth-java-cmd-lib/pom.xml @@ -10,7 +10,7 @@ powerauth-cmd-parent io.getlime.security - 1.4.0 + ${revision} diff --git a/powerauth-java-cmd/pom.xml b/powerauth-java-cmd/pom.xml index 89ce4b04..4ecfad90 100644 --- a/powerauth-java-cmd/pom.xml +++ b/powerauth-java-cmd/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-cmd-parent - 1.4.0 + ${revision} From c733ab9ba851b4131e2236df6f49a2d040702823 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 9 Dec 2022 16:42:00 +0100 Subject: [PATCH 02/53] Fix #261: Update to Spring Boot 2.7.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5c9d6e70..82d87121 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ 3.2.1 3.0.0 3.4.1 - 2.6.14 + 2.7.6 1.72 1.5.0 2.11.0 From d8f80c9b6c50f9d822e5cd1722859bf45a55215b Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 3 Jan 2023 11:50:55 +0100 Subject: [PATCH 03/53] Stop using revision property for project version Follow up to issue #269 --- pom.xml | 4 +--- powerauth-java-cmd-lib/pom.xml | 2 +- powerauth-java-cmd/pom.xml | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 82d87121..a833a3b9 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ io.getlime.security powerauth-cmd-parent - ${revision} + 1.5.0-SNAPSHOT pom 2016 @@ -72,8 +72,6 @@ - 1.5.0-SNAPSHOT - UTF-8 1.8 1.8 diff --git a/powerauth-java-cmd-lib/pom.xml b/powerauth-java-cmd-lib/pom.xml index db4fad90..c81b505b 100644 --- a/powerauth-java-cmd-lib/pom.xml +++ b/powerauth-java-cmd-lib/pom.xml @@ -10,7 +10,7 @@ powerauth-cmd-parent io.getlime.security - ${revision} + 1.5.0-SNAPSHOT diff --git a/powerauth-java-cmd/pom.xml b/powerauth-java-cmd/pom.xml index 4ecfad90..4082773a 100644 --- a/powerauth-java-cmd/pom.xml +++ b/powerauth-java-cmd/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-cmd-parent - ${revision} + 1.5.0-SNAPSHOT From 20a1e15b697d3458500ed6afdfc9d025ef6957c5 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 21 Feb 2023 07:16:02 +0100 Subject: [PATCH 04/53] Add dependabot configuration --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..81dcf707 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "weekly" From c402a719076b44002c624b1e9ec73e6b1056a45d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 08:41:38 +0000 Subject: [PATCH 05/53] Bump maven-javadoc-plugin from 3.4.1 to 3.5.0 Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.4.1 to 3.5.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.4.1...maven-javadoc-plugin-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a833a3b9..253e7660 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 1.8 3.2.1 3.0.0 - 3.4.1 + 3.5.0 2.7.6 1.72 1.5.0 From 7eb1c6ebb2fb6078353e46a9072f88522d01a5c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Tue, 21 Feb 2023 09:42:14 +0100 Subject: [PATCH 06/53] Fix #280: Update Wultra dependencies to snapshot (#281) * Fix #280: Update Wultra dependencies to snapshot * Change signatureFormat to signatureConfiguration --- pom.xml | 4 ++-- .../powerauth/lib/cmd/header/SignatureHeaderProvider.java | 6 ++++-- .../lib/cmd/steps/ComputeOfflineSignatureStep.java | 4 ++-- .../powerauth/lib/cmd/steps/v2/CreateTokenStep.java | 6 ++++-- .../security/powerauth/lib/cmd/steps/v2/RemoveStep.java | 6 ++++-- .../powerauth/lib/cmd/steps/v2/RemoveTokenStep.java | 6 ++++-- .../powerauth/lib/cmd/steps/v2/VaultUnlockStep.java | 6 ++++-- 7 files changed, 24 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index a833a3b9..58a19978 100644 --- a/pom.xml +++ b/pom.xml @@ -83,8 +83,8 @@ 1.5.0 2.11.0 1.1.1 - 1.4.0 - 1.6.0 + 1.5.0-SNAPSHOT + 1.7.0-SNAPSHOT 2.22.2 diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java index ac326737..089fc0e1 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java @@ -19,6 +19,7 @@ import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; +import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; @@ -74,7 +75,8 @@ public void addHeader(StepContext stepContext) // Compute the current PowerAuth signature for possession and knowledge factor String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString(requestContext.getSignatureHttpMethod(), requestContext.getSignatureRequestUri(), nonceBytes, requestBytes) + "&" + model.getApplicationSecret(); byte[] ctrData = CounterUtil.getCtrData(resultStatusObject, stepContext.getStepLogger()); - PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); + final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); + final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); List signatureSecretKeys; if (PowerAuthSignatureTypes.POSSESSION.equals(model.getSignatureType())) { @@ -86,7 +88,7 @@ public void addHeader(StepContext stepContext) SecretKey signatureKnowledgeKey = getSignatureKnowledgeKey(model); signatureSecretKeys = KEY_FACTORY.keysForSignatureType(model.getSignatureType(), signaturePossessionKey, signatureKnowledgeKey, signatureBiometryKey); } - String signatureValue = SIGNATURE.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), signatureSecretKeys, ctrData, signatureFormat); + String signatureValue = SIGNATURE.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), signatureSecretKeys, ctrData, signatureConfiguration); PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(resultStatusObject.getActivationId(), model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java index b8a29b80..5ff4dabe 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java @@ -17,7 +17,7 @@ package io.getlime.security.powerauth.lib.cmd.steps; import com.google.common.io.BaseEncoding; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; +import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.crypto.lib.util.SignatureUtils; @@ -223,7 +223,7 @@ private String calculateOfflineSignature(final String offlineData, final StepLog return SIGNATURE_UTILS.computePowerAuthSignature((signatureBaseString + "&offline").getBytes(StandardCharsets.UTF_8), signatureKeys, CounterUtil.getCtrData(resultStatusObject, stepLogger), - PowerAuthSignatureFormat.DECIMAL); + SignatureConfiguration.decimal()); } catch (Exception ex) { stepLogger.writeError(getStep().id() + "-error-cryptography", "Cryptography error", ex.getMessage()); stepLogger.writeDoneFailed(getStep().id() + "-failed"); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java index 8d0fbc66..42feccfa 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java @@ -23,6 +23,7 @@ import io.getlime.core.rest.model.base.request.ObjectRequest; import io.getlime.core.rest.model.base.response.ObjectResponse; import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; +import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesCryptogram; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; @@ -142,8 +143,9 @@ public ResultStatusObject execute(Map context) throws Exception // and knowledge factor String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/token/create", nonceBytes, requestBytes) + "&" + model.getApplicationSecret(); byte[] ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); - PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); - String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), Arrays.asList(signaturePossessionKey, signatureKnowledgeKey), ctrData, signatureFormat); + final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); + final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); + String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), Arrays.asList(signaturePossessionKey, signatureKnowledgeKey), ctrData, signatureConfiguration); PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); String httpAuthorizationHeader = header.buildHttpHeader(); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java index f6726c29..9daf5952 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java @@ -22,6 +22,7 @@ import com.wultra.core.rest.client.base.RestClientException; import io.getlime.core.rest.model.base.response.ObjectResponse; import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; +import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; @@ -126,8 +127,9 @@ public ResultStatusObject execute(Map context) throws Exception // and knowledge factor String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/activation/remove", nonceBytes, null) + "&" + model.getApplicationSecret(); byte[] ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); - PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); - String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), Arrays.asList(signaturePossessionKey, signatureKnowledgeKey), ctrData, signatureFormat); + final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); + final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); + String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), Arrays.asList(signaturePossessionKey, signatureKnowledgeKey), ctrData, signatureConfiguration); PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE.toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); String httpAuthorizationHeader = header.buildHttpHeader(); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java index b8efc0bd..4daf4fe1 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java @@ -24,6 +24,7 @@ import io.getlime.core.rest.model.base.response.ObjectResponse; import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; +import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; import io.getlime.security.powerauth.http.PowerAuthHttpBody; @@ -136,8 +137,9 @@ public ResultStatusObject execute(Map context) throws Exception // and knowledge factor String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/token/remove", nonceBytes, requestBytes) + "&" + model.getApplicationSecret(); byte[] ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); - PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); - String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), keyFactory.keysForSignatureType(model.getSignatureType(), signaturePossessionKey, signatureKnowledgeKey, signatureBiometryKey), ctrData, signatureFormat); + final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); + final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); + String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), keyFactory.keysForSignatureType(model.getSignatureType(), signaturePossessionKey, signatureKnowledgeKey, signatureBiometryKey), ctrData, signatureConfiguration); final PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); String httpAuthorizationHeader = header.buildHttpHeader(); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java index e20df992..062db656 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java @@ -25,6 +25,7 @@ import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; +import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; @@ -149,8 +150,9 @@ public ResultStatusObject execute(Map context) throws Exception // Compute the current PowerAuth signature for possession and knowledge factor String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/vault/unlock", nonceBytes, requestBytes) + "&" + model.getApplicationSecret(); byte[] ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); - PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); - String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), keyFactory.keysForSignatureType(model.getSignatureType(), signaturePossessionKey, signatureKnowledgeKey, signatureBiometryKey), ctrData, signatureFormat); + final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); + final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); + String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), keyFactory.keysForSignatureType(model.getSignatureType(), signaturePossessionKey, signatureKnowledgeKey, signatureBiometryKey), ctrData, signatureConfiguration); PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); String httpAuthorizationHeader = header.buildHttpHeader(); From 3ab8f848865de6bbc2b1def1728f4f361f703d6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Feb 2023 08:44:11 +0000 Subject: [PATCH 07/53] Bump maven-deploy-plugin from 3.0.0 to 3.1.0 Bumps [maven-deploy-plugin](https://github.com/apache/maven-deploy-plugin) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/apache/maven-deploy-plugin/releases) - [Commits](https://github.com/apache/maven-deploy-plugin/compare/maven-deploy-plugin-3.0.0...maven-deploy-plugin-3.1.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-deploy-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 07e74cc0..3fde6fb3 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 1.8 1.8 3.2.1 - 3.0.0 + 3.1.0 3.5.0 2.7.6 1.72 From ea7f237ed4679d5ab0a6664460d768aac1049916 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 18:11:49 +0000 Subject: [PATCH 08/53] Bump spring-boot.version from 2.7.6 to 2.7.9 Bumps `spring-boot.version` from 2.7.6 to 2.7.9. Updates `spring-boot-dependencies` from 2.7.6 to 2.7.9 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.6...v2.7.9) Updates `spring-boot-maven-plugin` from 2.7.6 to 2.7.9 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.6...v2.7.9) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 07e74cc0..3a998aa6 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.2.1 3.0.0 3.5.0 - 2.7.6 + 2.7.9 1.72 1.5.0 2.11.0 From c63d993fbf7a8bcc511d5830291ad5410e86882d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 18:03:57 +0000 Subject: [PATCH 09/53] Bump maven-surefire-plugin from 2.22.2 to 3.0.0 Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 2.22.2 to 3.0.0. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-2.22.2...surefire-3.0.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3a998aa6..7f9db20e 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 1.1.1 1.5.0-SNAPSHOT 1.7.0-SNAPSHOT - 2.22.2 + 3.0.0 From 4602775476eaecde23c75420dc53ab4b69cace49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 18:06:57 +0000 Subject: [PATCH 10/53] Bump spring-boot.version from 2.7.9 to 2.7.10 Bumps `spring-boot.version` from 2.7.9 to 2.7.10. Updates `spring-boot-dependencies` from 2.7.9 to 2.7.10 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.9...v2.7.10) Updates `spring-boot-maven-plugin` from 2.7.9 to 2.7.10 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.9...v2.7.10) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5d64d33a..515dba15 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.2.1 3.1.0 3.5.0 - 2.7.9 + 2.7.10 1.72 1.5.0 2.11.0 From 75d4da315bf21bcb859241f04eb33ffda4f3b4cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 18:07:10 +0000 Subject: [PATCH 11/53] Bump maven-deploy-plugin from 3.1.0 to 3.1.1 Bumps [maven-deploy-plugin](https://github.com/apache/maven-deploy-plugin) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/apache/maven-deploy-plugin/releases) - [Commits](https://github.com/apache/maven-deploy-plugin/compare/maven-deploy-plugin-3.1.0...maven-deploy-plugin-3.1.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-deploy-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5d64d33a..50d070ed 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 1.8 1.8 3.2.1 - 3.1.0 + 3.1.1 3.5.0 2.7.9 1.72 From a497e69a2fd3bca951cfb7aa7f1aecd338d27998 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 28 Mar 2023 09:37:19 +0200 Subject: [PATCH 12/53] Fix #292: Prefer Base64 Java 8 APIs over Guava --- .../cmd/header/SignatureHeaderProvider.java | 7 +-- .../lib/cmd/header/TokenHeaderProvider.java | 8 +-- .../lib/cmd/steps/AbstractActivationStep.java | 14 ++--- .../steps/ComputeOfflineSignatureStep.java | 18 +++--- .../cmd/steps/pojo/ResultStatusObject.java | 30 +++++----- .../cmd/steps/v2/CreateActivationStep.java | 56 +++++++++---------- .../lib/cmd/steps/v2/CreateTokenStep.java | 14 ++--- .../lib/cmd/steps/v2/EncryptStep.java | 36 ++++++------ .../lib/cmd/steps/v2/GetStatusStep.java | 6 +- .../cmd/steps/v2/PrepareActivationStep.java | 22 ++++---- .../lib/cmd/steps/v2/RemoveStep.java | 8 +-- .../lib/cmd/steps/v2/RemoveTokenStep.java | 4 +- .../lib/cmd/steps/v2/VaultUnlockStep.java | 18 +++--- .../lib/cmd/steps/v3/GetStatusStep.java | 8 +-- .../lib/cmd/steps/v3/VaultUnlockStep.java | 14 ++--- .../lib/cmd/util/ConfigurationUtil.java | 4 +- .../powerauth/lib/cmd/util/CounterUtil.java | 8 +-- .../powerauth/lib/cmd/util/SecurityUtil.java | 18 +++--- .../lib/cmd/util/VerifySignatureUtil.java | 4 +- 19 files changed, 142 insertions(+), 155 deletions(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java index 089fc0e1..0ed046d1 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java @@ -16,7 +16,6 @@ */ package io.getlime.security.powerauth.lib.cmd.header; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; @@ -90,16 +89,16 @@ public void addHeader(StepContext stepContext) } String signatureValue = SIGNATURE.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), signatureSecretKeys, ctrData, signatureConfiguration); - PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(resultStatusObject.getActivationId(), model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); + PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(resultStatusObject.getActivationId(), model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), Base64.getEncoder().encodeToString(nonceBytes), model.getVersion().value()); Map lowLevelData = new HashMap<>(); lowLevelData.put("counter", String.valueOf(resultStatusObject.getCounter())); int version = resultStatusObject.getVersion().intValue(); if (version == 3) { - lowLevelData.put("ctrData", BaseEncoding.base64().encode(ctrData)); + lowLevelData.put("ctrData", Base64.getEncoder().encodeToString(ctrData)); } lowLevelData.put("signatureBaseString", signatureBaseString); - lowLevelData.put("nonce", BaseEncoding.base64().encode(nonceBytes)); + lowLevelData.put("nonce", Base64.getEncoder().encodeToString(nonceBytes)); lowLevelData.put("applicationSecret", model.getApplicationSecret()); if (model instanceof VerifySignatureStepModel) { diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/TokenHeaderProvider.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/TokenHeaderProvider.java index 1b7f4325..e7b01dc9 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/TokenHeaderProvider.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/TokenHeaderProvider.java @@ -16,7 +16,6 @@ */ package io.getlime.security.powerauth.lib.cmd.header; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.client.token.ClientTokenGenerator; import io.getlime.security.powerauth.http.PowerAuthTokenHttpHeader; import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; @@ -24,6 +23,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.model.data.TokenHeaderData; import java.nio.charset.StandardCharsets; +import java.util.Base64; /** * Token header provider @@ -42,7 +42,7 @@ public void addHeader(StepContext stepContext) thr RequestContext requestContext = stepContext.getRequestContext(); String tokenId = model.getTokenId(); - byte[] tokenSecret = BaseEncoding.base64().decode(model.getTokenSecret()); + byte[] tokenSecret = Base64.getDecoder().decode(model.getTokenSecret()); ClientTokenGenerator tokenGenerator = new ClientTokenGenerator(); final byte[] tokenNonce = tokenGenerator.generateTokenNonce(); @@ -51,8 +51,8 @@ public void addHeader(StepContext stepContext) thr PowerAuthTokenHttpHeader header = new PowerAuthTokenHttpHeader( tokenId, - BaseEncoding.base64().encode(tokenDigest), - BaseEncoding.base64().encode(tokenNonce), + Base64.getEncoder().encodeToString(tokenDigest), + Base64.getEncoder().encodeToString(tokenNonce), new String(tokenTimestamp, StandardCharsets.UTF_8), model.getVersion().value() ); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java index 8b40cf9c..51b892ba 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java @@ -17,7 +17,6 @@ package io.getlime.security.powerauth.lib.cmd.steps; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; @@ -54,6 +53,7 @@ import java.security.KeyPair; import java.security.PublicKey; import java.security.interfaces.ECPublicKey; +import java.util.Base64; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -139,8 +139,8 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon ActivationSecurityContext securityContext = (ActivationSecurityContext) context.getSecurityContext(); // Read activation layer 1 response and decrypt it - byte[] macL1 = BaseEncoding.base64().decode(encryptedResponseL1.getMac()); - byte[] encryptedDataL1 = BaseEncoding.base64().decode(encryptedResponseL1.getEncryptedData()); + byte[] macL1 = Base64.getDecoder().decode(encryptedResponseL1.getMac()); + byte[] encryptedDataL1 = Base64.getDecoder().decode(encryptedResponseL1.getEncryptedData()); EciesCryptogram responseCryptogramL1 = new EciesCryptogram(macL1, encryptedDataL1); byte[] decryptedDataL1 = securityContext.getEncryptorL1().decryptResponse(responseCryptogramL1); @@ -156,8 +156,8 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon ); // Decrypt layer 2 response - byte[] macL2 = BaseEncoding.base64().decode(responseL1.getActivationData().getMac()); - byte[] encryptedDataL2 = BaseEncoding.base64().decode(responseL1.getActivationData().getEncryptedData()); + byte[] macL2 = Base64.getDecoder().decode(responseL1.getActivationData().getMac()); + byte[] encryptedDataL2 = Base64.getDecoder().decode(responseL1.getActivationData().getEncryptedData()); EciesCryptogram responseCryptogramL2 = new EciesCryptogram(macL2, encryptedDataL2); byte[] decryptedDataL2 = securityContext.getEncryptorL2().decryptResponse(responseCryptogramL2); @@ -175,7 +175,7 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon String activationId = responseL2.getActivationId(); String ctrDataBase64 = responseL2.getCtrData(); String serverPublicKeyBase64 = responseL2.getServerPublicKey(); - PublicKey serverPublicKey = KEY_CONVERTOR.convertBytesToPublicKey(BaseEncoding.base64().decode(serverPublicKeyBase64)); + PublicKey serverPublicKey = KEY_CONVERTOR.convertBytesToPublicKey(Base64.getDecoder().decode(serverPublicKeyBase64)); // Compute master secret key SecretKey masterSecretKey = KEY_FACTORY.generateClientMasterSecretKey(securityContext.getDeviceKeyPair().getPrivate(), serverPublicKey); @@ -286,7 +286,7 @@ protected void addEncryptedRequest(StepContext stepCo // Generate device key pair byte[] devicePublicKeyBytes = KEY_CONVERTOR.convertPublicKeyToBytes(securityContext.getDeviceKeyPair().getPublic()); - String devicePublicKeyBase64 = BaseEncoding.base64().encode(devicePublicKeyBytes); + String devicePublicKeyBase64 = Base64.getEncoder().encodeToString(devicePublicKeyBytes); // Create activation layer 2 request which is decryptable only on PowerAuth server ActivationLayer2Request requestL2 = new ActivationLayer2Request(); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java index 5ff4dabe..f9c0132c 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java @@ -16,7 +16,6 @@ */ package io.getlime.security.powerauth.lib.cmd.steps; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; @@ -42,10 +41,7 @@ import java.io.Console; import java.nio.charset.StandardCharsets; import java.security.interfaces.ECPublicKey; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Step for computing offline PowerAuth signature. @@ -184,12 +180,12 @@ private String calculateOfflineSignature(final String offlineData, final StepLog try { // Verify ECDSA signature from the offline data, return error in case of invalid signature final String ecdsaSignature = signatureLine.substring(1); - final byte[] serverPublicKeyBytes = BaseEncoding.base64().decode(resultStatusObject.getServerPublicKey()); + final byte[] serverPublicKeyBytes = Base64.getDecoder().decode(resultStatusObject.getServerPublicKey()); final ECPublicKey serverPublicKey = (ECPublicKey) KEY_CONVERTOR.convertBytesToPublicKey(serverPublicKeyBytes); final String offlineDataWithoutSignature = offlineData.substring(0, offlineData.length() - ecdsaSignature.length()); final boolean dataSignatureValid = SIGNATURE_UTILS.validateECDSASignature( offlineDataWithoutSignature.getBytes(StandardCharsets.UTF_8), - BaseEncoding.base64().decode(ecdsaSignature), + Base64.getDecoder().decode(ecdsaSignature), serverPublicKey); if (!dataSignatureValid) { stepLogger.writeError(getStep().id() + "-error-invalid-signature", "Invalid signature", "Invalid signature of offline data"); @@ -202,13 +198,13 @@ private String calculateOfflineSignature(final String offlineData, final StepLog final String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString( "POST", "/operation/authorize/offline", - BaseEncoding.base64().decode(nonce), + Base64.getDecoder().decode(nonce), dataForSignature.getBytes(StandardCharsets.UTF_8)); // Prepare keys for PowerAuth offline signature calculation - final byte[] signaturePossessionKeyBytes = BaseEncoding.base64().decode(resultStatusObject.getSignaturePossessionKey()); - final byte[] signatureKnowledgeKeySalt = BaseEncoding.base64().decode(resultStatusObject.getSignatureKnowledgeKeySalt()); - final byte[] signatureKnowledgeKeyEncryptedBytes = BaseEncoding.base64().decode(resultStatusObject.getSignatureKnowledgeKeyEncrypted()); + final byte[] signaturePossessionKeyBytes = Base64.getDecoder().decode(resultStatusObject.getSignaturePossessionKey()); + final byte[] signatureKnowledgeKeySalt = Base64.getDecoder().decode(resultStatusObject.getSignatureKnowledgeKeySalt()); + final byte[] signatureKnowledgeKeyEncryptedBytes = Base64.getDecoder().decode(resultStatusObject.getSignatureKnowledgeKeyEncrypted()); final SecretKey signaturePossessionKey = KEY_CONVERTOR.convertBytesToSharedSecretKey(signaturePossessionKeyBytes); final SecretKey signatureKnowledgeKey = EncryptedStorageUtil.getSignatureKnowledgeKey( password, diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/pojo/ResultStatusObject.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/pojo/ResultStatusObject.java index ed03d4f4..d01827e7 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/pojo/ResultStatusObject.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/pojo/ResultStatusObject.java @@ -16,7 +16,6 @@ package io.getlime.security.powerauth.lib.cmd.steps.pojo; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import lombok.AllArgsConstructor; import lombok.Data; @@ -27,6 +26,7 @@ import javax.crypto.SecretKey; import java.security.PublicKey; +import java.util.Base64; /** * Activation status object @@ -104,7 +104,7 @@ public void setCtrData(String ctrData) { @JsonIgnore public byte[] getEncryptedDevicePrivateKeyBytes() { String encryptedDevicePrivateKey = (String) jsonObject.get("encryptedDevicePrivateKey"); - return BaseEncoding.base64().decode(encryptedDevicePrivateKey); + return Base64.getDecoder().decode(encryptedDevicePrivateKey); } /** @@ -113,7 +113,7 @@ public byte[] getEncryptedDevicePrivateKeyBytes() { */ @JsonIgnore public void setEncryptedDevicePrivateKeyBytes(byte[] encryptedDevicePrivateKeyBytes) { - String encryptedDevicePrivateKey = BaseEncoding.base64().encode(encryptedDevicePrivateKeyBytes); + String encryptedDevicePrivateKey = Base64.getEncoder().encodeToString(encryptedDevicePrivateKeyBytes); jsonObject.put("encryptedDevicePrivateKey", encryptedDevicePrivateKey); } @@ -154,7 +154,7 @@ public void setResponseData(String responseData) { @JsonIgnore public PublicKey getServerPublicKeyObject() throws Exception { String serverPublicKey = (String) jsonObject.get("serverPublicKey"); - return KEY_CONVERTOR.convertBytesToPublicKey(BaseEncoding.base64().decode(serverPublicKey)); + return KEY_CONVERTOR.convertBytesToPublicKey(Base64.getDecoder().decode(serverPublicKey)); } /** @@ -164,7 +164,7 @@ public PublicKey getServerPublicKeyObject() throws Exception { */ @JsonIgnore public void setServerPublicKeyObject(PublicKey serverPublicKeyObject) throws Exception { - String serverPublicKey = BaseEncoding.base64().encode(KEY_CONVERTOR.convertPublicKeyToBytes(serverPublicKeyObject)); + String serverPublicKey = Base64.getEncoder().encodeToString(KEY_CONVERTOR.convertPublicKeyToBytes(serverPublicKeyObject)); jsonObject.put("serverPublicKey", serverPublicKey); } @@ -189,7 +189,7 @@ public void setServerPublicKey(String serverPublicKey) { @JsonIgnore public SecretKey getSignatureBiometryKeyObject() { String signatureBiometryKey = (String) jsonObject.get("signatureBiometryKey"); - return KEY_CONVERTOR.convertBytesToSharedSecretKey(BaseEncoding.base64().decode(signatureBiometryKey)); + return KEY_CONVERTOR.convertBytesToSharedSecretKey(Base64.getDecoder().decode(signatureBiometryKey)); } /** @@ -198,7 +198,7 @@ public SecretKey getSignatureBiometryKeyObject() { */ @JsonIgnore public void setSignatureBiometryKeyObject(SecretKey signatureBiometryKeyObject) { - String signatureBiometryKey = BaseEncoding.base64().encode(KEY_CONVERTOR.convertSharedSecretKeyToBytes(signatureBiometryKeyObject)); + String signatureBiometryKey = Base64.getEncoder().encodeToString(KEY_CONVERTOR.convertSharedSecretKeyToBytes(signatureBiometryKeyObject)); jsonObject.put("signatureBiometryKey", signatureBiometryKey); } @@ -223,7 +223,7 @@ public void setSignatureBiometryKey(String signatureBiometryKey) { @JsonIgnore public byte[] getSignatureKnowledgeKeyEncryptedBytes() { String signatureKnowledgeKeyEncrypted = (String) jsonObject.get("signatureKnowledgeKeyEncrypted"); - return BaseEncoding.base64().decode(signatureKnowledgeKeyEncrypted); + return Base64.getDecoder().decode(signatureKnowledgeKeyEncrypted); } /** @@ -232,7 +232,7 @@ public byte[] getSignatureKnowledgeKeyEncryptedBytes() { */ @JsonIgnore public void setSignatureKnowledgeKeyEncryptedBytes(byte[] signatureKnowledgeKeyEncryptedBytes) { - String signatureKnowledgeKeyEncrypted = BaseEncoding.base64().encode(signatureKnowledgeKeyEncryptedBytes); + String signatureKnowledgeKeyEncrypted = Base64.getEncoder().encodeToString(signatureKnowledgeKeyEncryptedBytes); jsonObject.put("signatureKnowledgeKeyEncrypted", signatureKnowledgeKeyEncrypted); } @@ -257,7 +257,7 @@ public void setSignatureKnowledgeKeyEncrypted(String signatureKnowledgeKeyEncryp @JsonIgnore public byte[] getSignatureKnowledgeKeySaltBytes() { String signatureKnowledgeKeySalt = (String) jsonObject.get("signatureKnowledgeKeySalt"); - return BaseEncoding.base64().decode(signatureKnowledgeKeySalt); + return Base64.getDecoder().decode(signatureKnowledgeKeySalt); } /** @@ -266,7 +266,7 @@ public byte[] getSignatureKnowledgeKeySaltBytes() { */ @JsonIgnore public void setSignatureKnowledgeKeySaltBytes(byte[] signatureKnowledgeKeySaltBytes) { - String signatureKnowledgeKeySalt = BaseEncoding.base64().encode(signatureKnowledgeKeySaltBytes); + String signatureKnowledgeKeySalt = Base64.getEncoder().encodeToString(signatureKnowledgeKeySaltBytes); jsonObject.put("signatureKnowledgeKeySalt", signatureKnowledgeKeySalt); } @@ -291,7 +291,7 @@ public void setSignatureKnowledgeKeySalt(String signatureKnowledgeKeySalt) { @JsonIgnore public SecretKey getSignaturePossessionKeyObject() { String signaturePossessionKey = (String) jsonObject.get("signaturePossessionKey"); - return KEY_CONVERTOR.convertBytesToSharedSecretKey(BaseEncoding.base64().decode(signaturePossessionKey)); + return KEY_CONVERTOR.convertBytesToSharedSecretKey(Base64.getDecoder().decode(signaturePossessionKey)); } /** @@ -300,7 +300,7 @@ public SecretKey getSignaturePossessionKeyObject() { */ @JsonIgnore public void setSignaturePossessionKeyObject(SecretKey signaturePossessionKeyObject) { - String signaturePossessionKey = BaseEncoding.base64().encode(KEY_CONVERTOR.convertSharedSecretKeyToBytes(signaturePossessionKeyObject)); + String signaturePossessionKey = Base64.getEncoder().encodeToString(KEY_CONVERTOR.convertSharedSecretKeyToBytes(signaturePossessionKeyObject)); jsonObject.put("signaturePossessionKey", signaturePossessionKey); } @@ -325,7 +325,7 @@ public void setSignaturePossessionKey(String signaturePossessionKey) { @JsonIgnore public SecretKey getTransportMasterKeyObject() { String transportMasterKey = (String) jsonObject.get("transportMasterKey"); - return KEY_CONVERTOR.convertBytesToSharedSecretKey(BaseEncoding.base64().decode(transportMasterKey)); + return KEY_CONVERTOR.convertBytesToSharedSecretKey(Base64.getDecoder().decode(transportMasterKey)); } /** @@ -334,7 +334,7 @@ public SecretKey getTransportMasterKeyObject() { */ @JsonIgnore public void setTransportMasterKeyObject(SecretKey transportMasterKeyObject) { - String transportMasterKey = BaseEncoding.base64().encode(KEY_CONVERTOR.convertSharedSecretKeyToBytes(transportMasterKeyObject)); + String transportMasterKey = Base64.getEncoder().encodeToString(KEY_CONVERTOR.convertSharedSecretKeyToBytes(transportMasterKeyObject)); jsonObject.put("transportMasterKey", transportMasterKey); } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateActivationStep.java index ed9019f2..be15b0cf 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateActivationStep.java @@ -1,7 +1,6 @@ package io.getlime.security.powerauth.lib.cmd.steps.v2; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.BaseEncoding; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; import io.getlime.core.rest.model.base.request.ObjectRequest; @@ -35,6 +34,7 @@ import java.net.URLEncoder; import java.security.KeyPair; import java.security.PublicKey; +import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -169,8 +169,8 @@ public ResultStatusObject execute(Map context) throws Exception activationIdShort, nonceDeviceBytes, cDevicePublicKeyBytes, - BaseEncoding.base64().decode(model.getApplicationKey()), - BaseEncoding.base64().decode(model.getApplicationSecret()) + Base64.getDecoder().decode(model.getApplicationKey()), + Base64.getDecoder().decode(model.getApplicationSecret()) ); byte[] ephemeralPublicKeyBytes = keyConvertor.convertPublicKeyToBytes(clientEphemeralKeyPair.getPublic()); @@ -179,10 +179,10 @@ public ResultStatusObject execute(Map context) throws Exception powerauth.setActivationIdShort(activationIdShort); powerauth.setApplicationKey(model.getApplicationKey()); powerauth.setActivationName(model.getActivationName()); - powerauth.setActivationNonce(BaseEncoding.base64().encode(nonceDeviceBytes)); - powerauth.setEphemeralPublicKey(BaseEncoding.base64().encode(ephemeralPublicKeyBytes)); - powerauth.setEncryptedDevicePublicKey(BaseEncoding.base64().encode(cDevicePublicKeyBytes)); - powerauth.setApplicationSignature(BaseEncoding.base64().encode(signature)); + powerauth.setActivationNonce(Base64.getEncoder().encodeToString(nonceDeviceBytes)); + powerauth.setEphemeralPublicKey(Base64.getEncoder().encodeToString(ephemeralPublicKeyBytes)); + powerauth.setEncryptedDevicePublicKey(Base64.getEncoder().encodeToString(cDevicePublicKeyBytes)); + powerauth.setApplicationSignature(Base64.getEncoder().encodeToString(signature)); ActivationCreateCustomRequest requestObject = new ActivationCreateCustomRequest(); requestObject.setIdentity(identityAttributes); @@ -201,19 +201,19 @@ public ResultStatusObject execute(Map context) throws Exception byte[] requestObjectBytes = mapper.writeValueAsBytes(requestObject); // Prepare the encryptor - ClientNonPersonalizedEncryptor encryptor = new ClientNonPersonalizedEncryptor(BaseEncoding.base64().decode(model.getApplicationKey()), model.getMasterPublicKey()); + ClientNonPersonalizedEncryptor encryptor = new ClientNonPersonalizedEncryptor(Base64.getDecoder().decode(model.getApplicationKey()), model.getMasterPublicKey()); // Encrypt the bytes final NonPersonalizedEncryptedMessage encryptedMessage = encryptor.encrypt(requestObjectBytes); NonPersonalizedEncryptedPayloadModel encryptedRequestObject = new NonPersonalizedEncryptedPayloadModel(); - encryptedRequestObject.setAdHocIndex(BaseEncoding.base64().encode(encryptedMessage.getAdHocIndex())); - encryptedRequestObject.setApplicationKey(BaseEncoding.base64().encode(encryptedMessage.getApplicationKey())); - encryptedRequestObject.setEncryptedData(BaseEncoding.base64().encode(encryptedMessage.getEncryptedData())); - encryptedRequestObject.setEphemeralPublicKey(BaseEncoding.base64().encode(encryptedMessage.getEphemeralPublicKey())); - encryptedRequestObject.setMac(BaseEncoding.base64().encode(encryptedMessage.getMac())); - encryptedRequestObject.setMacIndex(BaseEncoding.base64().encode(encryptedMessage.getMacIndex())); - encryptedRequestObject.setNonce(BaseEncoding.base64().encode(encryptedMessage.getNonce())); - encryptedRequestObject.setSessionIndex(BaseEncoding.base64().encode(encryptedMessage.getSessionIndex())); + encryptedRequestObject.setAdHocIndex(Base64.getEncoder().encodeToString(encryptedMessage.getAdHocIndex())); + encryptedRequestObject.setApplicationKey(Base64.getEncoder().encodeToString(encryptedMessage.getApplicationKey())); + encryptedRequestObject.setEncryptedData(Base64.getEncoder().encodeToString(encryptedMessage.getEncryptedData())); + encryptedRequestObject.setEphemeralPublicKey(Base64.getEncoder().encodeToString(encryptedMessage.getEphemeralPublicKey())); + encryptedRequestObject.setMac(Base64.getEncoder().encodeToString(encryptedMessage.getMac())); + encryptedRequestObject.setMacIndex(Base64.getEncoder().encodeToString(encryptedMessage.getMacIndex())); + encryptedRequestObject.setNonce(Base64.getEncoder().encodeToString(encryptedMessage.getNonce())); + encryptedRequestObject.setSessionIndex(Base64.getEncoder().encodeToString(encryptedMessage.getSessionIndex())); ObjectRequest body = new ObjectRequest<>(); body.setRequestObject(encryptedRequestObject); @@ -256,14 +256,14 @@ public ResultStatusObject execute(Map context) throws Exception // Decrypt the server response final NonPersonalizedEncryptedPayloadModel encryptedResponseObject = responseWrapper.getResponseObject(); - encryptedMessage.setApplicationKey(BaseEncoding.base64().decode(encryptedResponseObject.getApplicationKey())); - encryptedMessage.setAdHocIndex(BaseEncoding.base64().decode(encryptedResponseObject.getAdHocIndex())); - encryptedMessage.setEphemeralPublicKey(BaseEncoding.base64().decode(encryptedResponseObject.getEphemeralPublicKey())); - encryptedMessage.setEncryptedData(BaseEncoding.base64().decode(encryptedResponseObject.getEncryptedData())); - encryptedMessage.setMac(BaseEncoding.base64().decode(encryptedResponseObject.getMac())); - encryptedMessage.setMacIndex(BaseEncoding.base64().decode(encryptedResponseObject.getMacIndex())); - encryptedMessage.setNonce(BaseEncoding.base64().decode(encryptedResponseObject.getNonce())); - encryptedMessage.setSessionIndex(BaseEncoding.base64().decode(encryptedResponseObject.getSessionIndex())); + encryptedMessage.setApplicationKey(Base64.getDecoder().decode(encryptedResponseObject.getApplicationKey())); + encryptedMessage.setAdHocIndex(Base64.getDecoder().decode(encryptedResponseObject.getAdHocIndex())); + encryptedMessage.setEphemeralPublicKey(Base64.getDecoder().decode(encryptedResponseObject.getEphemeralPublicKey())); + encryptedMessage.setEncryptedData(Base64.getDecoder().decode(encryptedResponseObject.getEncryptedData())); + encryptedMessage.setMac(Base64.getDecoder().decode(encryptedResponseObject.getMac())); + encryptedMessage.setMacIndex(Base64.getDecoder().decode(encryptedResponseObject.getMacIndex())); + encryptedMessage.setNonce(Base64.getDecoder().decode(encryptedResponseObject.getNonce())); + encryptedMessage.setSessionIndex(Base64.getDecoder().decode(encryptedResponseObject.getSessionIndex())); byte[] originalResponseObjectBytes = encryptor.decrypt(encryptedMessage); ActivationCreateResponse responseObject = mapper.readValue(originalResponseObjectBytes, ActivationCreateResponse.class); @@ -277,10 +277,10 @@ public ResultStatusObject execute(Map context) throws Exception // Process the response object String activationId = responseObject.getActivationId(); - byte[] nonceServerBytes = BaseEncoding.base64().decode(responseObject.getActivationNonce()); - byte[] cServerPubKeyBytes = BaseEncoding.base64().decode(responseObject.getEncryptedServerPublicKey()); - byte[] cServerPubKeySignatureBytes = BaseEncoding.base64().decode(responseObject.getEncryptedServerPublicKeySignature()); - byte[] ephemeralKeyBytes = BaseEncoding.base64().decode(responseObject.getEphemeralPublicKey()); + byte[] nonceServerBytes = Base64.getDecoder().decode(responseObject.getActivationNonce()); + byte[] cServerPubKeyBytes = Base64.getDecoder().decode(responseObject.getEncryptedServerPublicKey()); + byte[] cServerPubKeySignatureBytes = Base64.getDecoder().decode(responseObject.getEncryptedServerPublicKeySignature()); + byte[] ephemeralKeyBytes = Base64.getDecoder().decode(responseObject.getEphemeralPublicKey()); PublicKey ephemeralPublicKey = keyConvertor.convertBytesToPublicKey(ephemeralKeyBytes); // Verify that the server public key signature is valid diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java index 42feccfa..75e941a9 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java @@ -17,7 +17,6 @@ package io.getlime.security.powerauth.lib.cmd.steps.v2; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.BaseEncoding; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; import io.getlime.core.rest.model.base.request.ObjectRequest; @@ -49,10 +48,7 @@ import java.io.FileWriter; import java.nio.charset.StandardCharsets; import java.security.interfaces.ECPublicKey; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; /** * Helper class with token creation logic. @@ -132,7 +128,7 @@ public ResultStatusObject execute(Map context) throws Exception final EciesCryptogram eciesCryptogram = encryptor.encryptRequest(new byte[0], false); // Prepare encryption request TokenCreateRequest requestObject = new TokenCreateRequest(); - String ephemeralPublicKeyBase64 = BaseEncoding.base64().encode(eciesCryptogram.getEphemeralPublicKey()); + String ephemeralPublicKeyBase64 = Base64.getEncoder().encodeToString(eciesCryptogram.getEphemeralPublicKey()); requestObject.setEphemeralPublicKey(ephemeralPublicKeyBase64); final ObjectRequest request = new ObjectRequest<>(requestObject); @@ -146,7 +142,7 @@ public ResultStatusObject execute(Map context) throws Exception final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), Arrays.asList(signaturePossessionKey, signatureKnowledgeKey), ctrData, signatureConfiguration); - PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); + PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), Base64.getEncoder().encodeToString(nonceBytes), model.getVersion().value()); String httpAuthorizationHeader = header.buildHttpHeader(); // Increment the counter @@ -189,8 +185,8 @@ public ResultStatusObject execute(Map context) throws Exception final TokenCreateResponse responseObject = responseWrapper.getResponseObject(); - byte[] macResponse = BaseEncoding.base64().decode(responseObject.getMac()); - byte[] encryptedDataResponse = BaseEncoding.base64().decode(responseObject.getEncryptedData()); + byte[] macResponse = Base64.getDecoder().decode(responseObject.getMac()); + byte[] encryptedDataResponse = Base64.getDecoder().decode(responseObject.getEncryptedData()); EciesCryptogram eciesCryptogramResponse = new EciesCryptogram(macResponse, encryptedDataResponse); final byte[] decryptedBytes = encryptor.decryptResponse(eciesCryptogramResponse); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/EncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/EncryptStep.java index 38bc109e..2313775a 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/EncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/EncryptStep.java @@ -16,7 +16,6 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v2; -import com.google.common.io.BaseEncoding; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; import io.getlime.core.rest.model.base.request.ObjectRequest; @@ -38,6 +37,7 @@ import org.springframework.stereotype.Component; import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -98,7 +98,7 @@ public ResultStatusObject execute(Map context) throws Exception return null; } // Prepare the encryptor - ClientNonPersonalizedEncryptor encryptor = new ClientNonPersonalizedEncryptor(BaseEncoding.base64().decode(model.getApplicationKey()), model.getMasterPublicKey()); + ClientNonPersonalizedEncryptor encryptor = new ClientNonPersonalizedEncryptor(Base64.getDecoder().decode(model.getApplicationKey()), model.getMasterPublicKey()); // Encrypt the request data final NonPersonalizedEncryptedMessage encryptedMessage = encryptor.encrypt(requestDataBytes); @@ -109,14 +109,14 @@ public ResultStatusObject execute(Map context) throws Exception } NonPersonalizedEncryptedPayloadModel encryptedRequestObject = new NonPersonalizedEncryptedPayloadModel(); - encryptedRequestObject.setAdHocIndex(BaseEncoding.base64().encode(encryptedMessage.getAdHocIndex())); - encryptedRequestObject.setApplicationKey(BaseEncoding.base64().encode(encryptedMessage.getApplicationKey())); - encryptedRequestObject.setEncryptedData(BaseEncoding.base64().encode(encryptedMessage.getEncryptedData())); - encryptedRequestObject.setEphemeralPublicKey(BaseEncoding.base64().encode(encryptedMessage.getEphemeralPublicKey())); - encryptedRequestObject.setMac(BaseEncoding.base64().encode(encryptedMessage.getMac())); - encryptedRequestObject.setMacIndex(BaseEncoding.base64().encode(encryptedMessage.getMacIndex())); - encryptedRequestObject.setNonce(BaseEncoding.base64().encode(encryptedMessage.getNonce())); - encryptedRequestObject.setSessionIndex(BaseEncoding.base64().encode(encryptedMessage.getSessionIndex())); + encryptedRequestObject.setAdHocIndex(Base64.getEncoder().encodeToString(encryptedMessage.getAdHocIndex())); + encryptedRequestObject.setApplicationKey(Base64.getEncoder().encodeToString(encryptedMessage.getApplicationKey())); + encryptedRequestObject.setEncryptedData(Base64.getEncoder().encodeToString(encryptedMessage.getEncryptedData())); + encryptedRequestObject.setEphemeralPublicKey(Base64.getEncoder().encodeToString(encryptedMessage.getEphemeralPublicKey())); + encryptedRequestObject.setMac(Base64.getEncoder().encodeToString(encryptedMessage.getMac())); + encryptedRequestObject.setMacIndex(Base64.getEncoder().encodeToString(encryptedMessage.getMacIndex())); + encryptedRequestObject.setNonce(Base64.getEncoder().encodeToString(encryptedMessage.getNonce())); + encryptedRequestObject.setSessionIndex(Base64.getEncoder().encodeToString(encryptedMessage.getSessionIndex())); ObjectRequest body = new ObjectRequest<>(); body.setRequestObject(encryptedRequestObject); @@ -159,14 +159,14 @@ public ResultStatusObject execute(Map context) throws Exception // Decrypt the server response final NonPersonalizedEncryptedPayloadModel encryptedResponseObject = responseWrapper.getResponseObject(); - encryptedMessage.setApplicationKey(BaseEncoding.base64().decode(encryptedResponseObject.getApplicationKey())); - encryptedMessage.setAdHocIndex(BaseEncoding.base64().decode(encryptedResponseObject.getAdHocIndex())); - encryptedMessage.setEphemeralPublicKey(BaseEncoding.base64().decode(encryptedResponseObject.getEphemeralPublicKey())); - encryptedMessage.setEncryptedData(BaseEncoding.base64().decode(encryptedResponseObject.getEncryptedData())); - encryptedMessage.setMac(BaseEncoding.base64().decode(encryptedResponseObject.getMac())); - encryptedMessage.setMacIndex(BaseEncoding.base64().decode(encryptedResponseObject.getMacIndex())); - encryptedMessage.setNonce(BaseEncoding.base64().decode(encryptedResponseObject.getNonce())); - encryptedMessage.setSessionIndex(BaseEncoding.base64().decode(encryptedResponseObject.getSessionIndex())); + encryptedMessage.setApplicationKey(Base64.getDecoder().decode(encryptedResponseObject.getApplicationKey())); + encryptedMessage.setAdHocIndex(Base64.getDecoder().decode(encryptedResponseObject.getAdHocIndex())); + encryptedMessage.setEphemeralPublicKey(Base64.getDecoder().decode(encryptedResponseObject.getEphemeralPublicKey())); + encryptedMessage.setEncryptedData(Base64.getDecoder().decode(encryptedResponseObject.getEncryptedData())); + encryptedMessage.setMac(Base64.getDecoder().decode(encryptedResponseObject.getMac())); + encryptedMessage.setMacIndex(Base64.getDecoder().decode(encryptedResponseObject.getMacIndex())); + encryptedMessage.setNonce(Base64.getDecoder().decode(encryptedResponseObject.getNonce())); + encryptedMessage.setSessionIndex(Base64.getDecoder().decode(encryptedResponseObject.getSessionIndex())); byte[] decryptedMessageBytes = encryptor.decrypt(encryptedMessage); if (decryptedMessageBytes == null) { diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/GetStatusStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/GetStatusStep.java index a256b632..a2f97749 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/GetStatusStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/GetStatusStep.java @@ -16,7 +16,6 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v2; -import com.google.common.io.BaseEncoding; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; import io.getlime.core.rest.model.base.request.ObjectRequest; @@ -41,6 +40,7 @@ import org.springframework.stereotype.Component; import javax.crypto.SecretKey; +import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -100,7 +100,7 @@ public ResultStatusObject execute(Map context) { // Get data from status final String activationId = resultStatusObject.getActivationId(); final String transportMasterKeyBase64 = resultStatusObject.getTransportMasterKey(); - final SecretKey transportMasterKey = keyConvertor.convertBytesToSharedSecretKey(BaseEncoding.base64().decode(transportMasterKeyBase64)); + final SecretKey transportMasterKey = keyConvertor.convertBytesToSharedSecretKey(Base64.getDecoder().decode(transportMasterKeyBase64)); // Send the activation status request to the server final ActivationStatusRequest requestObject = new ActivationStatusRequest(); @@ -138,7 +138,7 @@ public ResultStatusObject execute(Map context) { // Process the server response final ActivationStatusResponse responseObject = responseWrapper.getResponseObject(); - final byte[] cStatusBlob = BaseEncoding.base64().decode(responseObject.getEncryptedStatusBlob()); + final byte[] cStatusBlob = Base64.getDecoder().decode(responseObject.getEncryptedStatusBlob()); // Print the results final ActivationStatusBlobInfo statusBlobRaw = activation.getStatusFromEncryptedBlob(cStatusBlob, null, null, transportMasterKey); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/PrepareActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/PrepareActivationStep.java index 2839a82d..f7487ebf 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/PrepareActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/PrepareActivationStep.java @@ -17,7 +17,6 @@ package io.getlime.security.powerauth.lib.cmd.steps.v2; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.BaseEncoding; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; import io.getlime.core.rest.model.base.request.ObjectRequest; @@ -45,6 +44,7 @@ import java.io.FileWriter; import java.security.KeyPair; import java.security.PublicKey; +import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -148,8 +148,8 @@ public ResultStatusObject execute(Map context) throws Exception activationIdShort, nonceDeviceBytes, cDevicePublicKeyBytes, - BaseEncoding.base64().decode(model.getApplicationKey()), - BaseEncoding.base64().decode(model.getApplicationSecret()) + Base64.getDecoder().decode(model.getApplicationKey()), + Base64.getDecoder().decode(model.getApplicationSecret()) ); byte[] ephemeralPublicKeyBytes = keyConversion.convertPublicKeyToBytes(clientEphemeralKeyPair.getPublic()); @@ -158,10 +158,10 @@ public ResultStatusObject execute(Map context) throws Exception requestObject.setActivationIdShort(activationIdShort); requestObject.setApplicationKey(model.getApplicationKey()); requestObject.setActivationName(model.getActivationName()); - requestObject.setActivationNonce(BaseEncoding.base64().encode(nonceDeviceBytes)); - requestObject.setEphemeralPublicKey(BaseEncoding.base64().encode(ephemeralPublicKeyBytes)); - requestObject.setEncryptedDevicePublicKey(BaseEncoding.base64().encode(cDevicePublicKeyBytes)); - requestObject.setApplicationSignature(BaseEncoding.base64().encode(signature)); + requestObject.setActivationNonce(Base64.getEncoder().encodeToString(nonceDeviceBytes)); + requestObject.setEphemeralPublicKey(Base64.getEncoder().encodeToString(ephemeralPublicKeyBytes)); + requestObject.setEncryptedDevicePublicKey(Base64.getEncoder().encodeToString(cDevicePublicKeyBytes)); + requestObject.setApplicationSignature(Base64.getEncoder().encodeToString(signature)); ObjectRequest body = new ObjectRequest<>(); body.setRequestObject(requestObject); @@ -197,10 +197,10 @@ public ResultStatusObject execute(Map context) throws Exception // Process the server response ActivationCreateResponse responseObject = responseWrapper.getResponseObject(); String activationId = responseObject.getActivationId(); - byte[] nonceServerBytes = BaseEncoding.base64().decode(responseObject.getActivationNonce()); - byte[] cServerPubKeyBytes = BaseEncoding.base64().decode(responseObject.getEncryptedServerPublicKey()); - byte[] cServerPubKeySignatureBytes = BaseEncoding.base64().decode(responseObject.getEncryptedServerPublicKeySignature()); - byte[] ephemeralKeyBytes = BaseEncoding.base64().decode(responseObject.getEphemeralPublicKey()); + byte[] nonceServerBytes = Base64.getDecoder().decode(responseObject.getActivationNonce()); + byte[] cServerPubKeyBytes = Base64.getDecoder().decode(responseObject.getEncryptedServerPublicKey()); + byte[] cServerPubKeySignatureBytes = Base64.getDecoder().decode(responseObject.getEncryptedServerPublicKeySignature()); + byte[] ephemeralKeyBytes = Base64.getDecoder().decode(responseObject.getEphemeralPublicKey()); PublicKey ephemeralPublicKey = keyConversion.convertBytesToPublicKey(ephemeralKeyBytes); // Verify that the server public key signature is valid diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java index 9daf5952..5488ff49 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java @@ -17,7 +17,6 @@ package io.getlime.security.powerauth.lib.cmd.steps.v2; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.BaseEncoding; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; import io.getlime.core.rest.model.base.response.ObjectResponse; @@ -44,10 +43,7 @@ import java.io.Console; import java.io.FileWriter; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; /** * Helper class with activation remove logic. @@ -130,7 +126,7 @@ public ResultStatusObject execute(Map context) throws Exception final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), Arrays.asList(signaturePossessionKey, signatureKnowledgeKey), ctrData, signatureConfiguration); - PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE.toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); + PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE.toString(), Base64.getEncoder().encodeToString(nonceBytes), model.getVersion().value()); String httpAuthorizationHeader = header.buildHttpHeader(); // Increment the counter diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java index 4daf4fe1..0bc93bb7 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java @@ -17,7 +17,6 @@ package io.getlime.security.powerauth.lib.cmd.steps.v2; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.BaseEncoding; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; import io.getlime.core.rest.model.base.request.ObjectRequest; @@ -46,6 +45,7 @@ import java.io.Console; import java.io.FileWriter; import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -140,7 +140,7 @@ public ResultStatusObject execute(Map context) throws Exception final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), keyFactory.keysForSignatureType(model.getSignatureType(), signaturePossessionKey, signatureKnowledgeKey, signatureBiometryKey), ctrData, signatureConfiguration); - final PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); + final PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), Base64.getEncoder().encodeToString(nonceBytes), model.getVersion().value()); String httpAuthorizationHeader = header.buildHttpHeader(); // Increment the counter diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java index 062db656..26bb13d0 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java @@ -17,7 +17,6 @@ package io.getlime.security.powerauth.lib.cmd.steps.v2; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.BaseEncoding; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; import io.getlime.core.rest.model.base.request.ObjectRequest; @@ -50,6 +49,7 @@ import java.nio.charset.StandardCharsets; import java.security.PrivateKey; import java.security.PublicKey; +import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -114,9 +114,9 @@ public ResultStatusObject execute(Map context) throws Exception String activationId = resultStatusObject.getActivationId(); byte[] signatureKnowledgeKeySalt = resultStatusObject.getSignatureKnowledgeKeySaltBytes(); byte[] signatureKnowledgeKeyEncryptedBytes = resultStatusObject.getSignatureKnowledgeKeyEncryptedBytes(); - byte[] transportMasterKeyBytes = BaseEncoding.base64().decode(resultStatusObject.getTransportMasterKey()); + byte[] transportMasterKeyBytes = Base64.getDecoder().decode(resultStatusObject.getTransportMasterKey()); byte[] encryptedDevicePrivateKeyBytes = resultStatusObject.getEncryptedDevicePrivateKeyBytes(); - byte[] serverPublicKeyBytes = BaseEncoding.base64().decode(resultStatusObject.getServerPublicKey()); + byte[] serverPublicKeyBytes = Base64.getDecoder().decode(resultStatusObject.getServerPublicKey()); // Ask for the password to unlock knowledge factor key char[] password; @@ -153,7 +153,7 @@ public ResultStatusObject execute(Map context) throws Exception final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), keyFactory.keysForSignatureType(model.getSignatureType(), signaturePossessionKey, signatureKnowledgeKey, signatureBiometryKey), ctrData, signatureConfiguration); - PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), BaseEncoding.base64().encode(nonceBytes), model.getVersion().value()); + PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), Base64.getEncoder().encodeToString(nonceBytes), model.getVersion().value()); String httpAuthorizationHeader = header.buildHttpHeader(); // Increment the counter @@ -205,7 +205,7 @@ public ResultStatusObject execute(Map context) throws Exception stepLogger.writeServerCallOK("vault-unlock-response-received", responseWrapper, HttpUtil.flattenHttpHeaders(responseEntity.getHeaders())); VaultUnlockResponse responseObject = responseWrapper.getResponseObject(); - byte[] encryptedVaultEncryptionKey = BaseEncoding.base64().decode(responseObject.getEncryptedVaultEncryptionKey()); + byte[] encryptedVaultEncryptionKey = Base64.getDecoder().decode(responseObject.getEncryptedVaultEncryptionKey()); PowerAuthClientVault vault = new PowerAuthClientVault(); ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); @@ -229,10 +229,10 @@ public ResultStatusObject execute(Map context) throws Exception // Print the results Map objectMap = new HashMap<>(); objectMap.put("activationId", activationId); - objectMap.put("encryptedVaultEncryptionKey", BaseEncoding.base64().encode(encryptedVaultEncryptionKey)); - objectMap.put("transportMasterKey", BaseEncoding.base64().encode(keyConvertor.convertSharedSecretKeyToBytes(transportMasterKey))); - objectMap.put("vaultEncryptionKey", BaseEncoding.base64().encode(keyConvertor.convertSharedSecretKeyToBytes(vaultEncryptionKey))); - objectMap.put("devicePrivateKey", BaseEncoding.base64().encode(keyConvertor.convertPrivateKeyToBytes(devicePrivateKey))); + objectMap.put("encryptedVaultEncryptionKey", Base64.getEncoder().encodeToString(encryptedVaultEncryptionKey)); + objectMap.put("transportMasterKey", Base64.getEncoder().encodeToString(keyConvertor.convertSharedSecretKeyToBytes(transportMasterKey))); + objectMap.put("vaultEncryptionKey", Base64.getEncoder().encodeToString(keyConvertor.convertSharedSecretKeyToBytes(vaultEncryptionKey))); + objectMap.put("devicePrivateKey", Base64.getEncoder().encodeToString(keyConvertor.convertPrivateKeyToBytes(devicePrivateKey))); objectMap.put("privateKeyDecryptionSuccessful", (equal ? "true" : "false")); stepLogger.writeItem( diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java index fa2186bf..d9c36b62 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java @@ -15,7 +15,6 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v3; -import com.google.common.io.BaseEncoding; import io.getlime.core.rest.model.base.request.ObjectRequest; import io.getlime.core.rest.model.base.response.ObjectResponse; import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; @@ -39,6 +38,7 @@ import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; +import java.util.Base64; import java.util.HashMap; import java.util.Map; @@ -122,7 +122,7 @@ public StepContext> // Send the activation status request to the server final ActivationStatusRequest requestObject = new ActivationStatusRequest(); requestObject.setActivationId(model.getResultStatus().getActivationId()); - requestObject.setChallenge(challenge != null ? BaseEncoding.base64().encode(challenge) : null); + requestObject.setChallenge(challenge != null ? Base64.getEncoder().encodeToString(challenge) : null); final ObjectRequest body = new ObjectRequest<>(); body.setRequestObject(requestObject); @@ -139,8 +139,8 @@ public void processResponse(StepContext customObject = responseObject.getCustomObject(); byte[] challenge = (byte[]) stepContext.getAttributes().get(ATTRIBUTE_CHALLENGE); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java index 1394dae2..ebac8dab 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java @@ -15,7 +15,6 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v3; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; @@ -24,9 +23,9 @@ import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.header.PowerAuthHeaderFactory; import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; import io.getlime.security.powerauth.lib.cmd.logging.StepLoggerFactory; -import io.getlime.security.powerauth.lib.cmd.header.PowerAuthHeaderFactory; import io.getlime.security.powerauth.lib.cmd.status.ResultStatusService; import io.getlime.security.powerauth.lib.cmd.steps.AbstractBaseStep; import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; @@ -44,6 +43,7 @@ import javax.crypto.SecretKey; import java.security.PrivateKey; import java.security.PublicKey; +import java.util.Base64; import java.util.HashMap; import java.util.Map; @@ -138,7 +138,7 @@ public void processResponse(StepContext objectMap = new HashMap<>(); objectMap.put("activationId", resultStatusObject.getActivationId()); - objectMap.put("encryptedVaultEncryptionKey", BaseEncoding.base64().encode(encryptedVaultEncryptionKey)); - objectMap.put("transportMasterKey", BaseEncoding.base64().encode(KEY_CONVERTOR.convertSharedSecretKeyToBytes(transportMasterKey))); - objectMap.put("vaultEncryptionKey", BaseEncoding.base64().encode(KEY_CONVERTOR.convertSharedSecretKeyToBytes(vaultEncryptionKey))); - objectMap.put("devicePrivateKey", BaseEncoding.base64().encode(KEY_CONVERTOR.convertPrivateKeyToBytes(devicePrivateKey))); + objectMap.put("encryptedVaultEncryptionKey", Base64.getEncoder().encodeToString(encryptedVaultEncryptionKey)); + objectMap.put("transportMasterKey", Base64.getEncoder().encodeToString(KEY_CONVERTOR.convertSharedSecretKeyToBytes(transportMasterKey))); + objectMap.put("vaultEncryptionKey", Base64.getEncoder().encodeToString(KEY_CONVERTOR.convertSharedSecretKeyToBytes(vaultEncryptionKey))); + objectMap.put("devicePrivateKey", Base64.getEncoder().encodeToString(KEY_CONVERTOR.convertPrivateKeyToBytes(devicePrivateKey))); objectMap.put("privateKeyDecryptionSuccessful", (equal ? "true" : "false")); stepContext.getStepLogger().writeItem( diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/ConfigurationUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/ConfigurationUtil.java index 0251db07..d204853b 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/ConfigurationUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/ConfigurationUtil.java @@ -16,7 +16,6 @@ */ package io.getlime.security.powerauth.lib.cmd.util; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.lib.model.exception.CryptoProviderException; import io.getlime.security.powerauth.crypto.lib.model.exception.GenericCryptoException; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; @@ -25,6 +24,7 @@ import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; +import java.util.Base64; /** * Helper class for configuration @@ -81,7 +81,7 @@ public static String getApplicationName(JSONObject clientConfigObject) { public static PublicKey getMasterKey(JSONObject clientConfigObject, StepLogger stepLogger) { if (clientConfigObject != null && clientConfigObject.get("masterPublicKey") != null) { try { - byte[] masterKeyBytes = BaseEncoding.base64().decode((String) clientConfigObject.get("masterPublicKey")); + byte[] masterKeyBytes = Base64.getDecoder().decode((String) clientConfigObject.get("masterPublicKey")); return keyConvertor.convertBytesToPublicKey(masterKeyBytes); } catch (IllegalArgumentException e) { stepLogger.writeError("master-key-error-encoding", "Invalid Master Server Public Key", "Master Server Public Key must be stored in a valid Base64 encoding", e); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java index eb14800b..772bd0b9 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java @@ -16,7 +16,6 @@ */ package io.getlime.security.powerauth.lib.cmd.util; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.lib.generator.HashBasedCounter; import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.BaseStepModel; @@ -24,6 +23,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; import java.nio.ByteBuffer; +import java.util.Base64; /** * Helper class for counter. @@ -65,7 +65,7 @@ public static byte[] getCtrData(ResultStatusObject resultStatusObject, StepLogge case 3: String ctrDataBase64 = resultStatusObject.getCtrData(); if (!ctrDataBase64.isEmpty()) { - ctrData = BaseEncoding.base64().decode(ctrDataBase64); + ctrData = Base64.getDecoder().decode(ctrDataBase64); } break; default: @@ -102,9 +102,9 @@ public static void incrementCounter(BaseStepData model) { if (version == 3) { String ctrDataBase64 = resultStatusObject.getCtrData(); if (!ctrDataBase64.isEmpty()) { - byte[] ctrData = BaseEncoding.base64().decode(ctrDataBase64); + byte[] ctrData = Base64.getDecoder().decode(ctrDataBase64); ctrData = new HashBasedCounter().next(ctrData); - resultStatusObject.setCtrData(BaseEncoding.base64().encode(ctrData)); + resultStatusObject.setCtrData(Base64.getEncoder().encodeToString(ctrData)); } } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java index 1894a133..7227ea0a 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java @@ -16,7 +16,6 @@ */ package io.getlime.security.powerauth.lib.cmd.util; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.exception.EciesException; @@ -34,6 +33,7 @@ import java.nio.charset.StandardCharsets; import java.security.interfaces.ECPublicKey; import java.security.spec.InvalidKeySpecException; +import java.util.Base64; /** * Helper class with security utilities. @@ -69,8 +69,8 @@ public static EciesEncryptor createEncryptor(String applicationSecretValue, EciesSharedInfo1 sharedInfo) throws CryptoProviderException, GenericCryptoException, InvalidKeySpecException { byte[] applicationSecret = applicationSecretValue.getBytes(StandardCharsets.UTF_8); - byte[] serverPublicKeyBytes = BaseEncoding.base64().decode(resultStatusObject.getServerPublicKey()); - byte[] transportMasterKeyBytes = BaseEncoding.base64().decode(resultStatusObject.getTransportMasterKey()); + byte[] serverPublicKeyBytes = Base64.getDecoder().decode(resultStatusObject.getServerPublicKey()); + byte[] transportMasterKeyBytes = Base64.getDecoder().decode(resultStatusObject.getTransportMasterKey()); final ECPublicKey serverPublicKey = (ECPublicKey) KEY_CONVERTOR.convertBytesToPublicKey(serverPublicKeyBytes); return ECIES_FACTORY.getEciesEncryptorForActivation(serverPublicKey, applicationSecret, transportMasterKeyBytes, sharedInfo); @@ -105,8 +105,8 @@ public static EciesCryptogram encryptObject(EciesEncryptor encryptor, Object val */ public static byte[] decryptBytesFromResponse(EciesEncryptor encryptor, EciesEncryptedResponse encryptedResponse) throws EciesException { - byte[] macResponse = BaseEncoding.base64().decode(encryptedResponse.getMac()); - byte[] encryptedDataResponse = BaseEncoding.base64().decode(encryptedResponse.getEncryptedData()); + byte[] macResponse = Base64.getDecoder().decode(encryptedResponse.getMac()); + byte[] encryptedDataResponse = Base64.getDecoder().decode(encryptedResponse.getEncryptedData()); final EciesCryptogram eciesCryptogramResponse = new EciesCryptogram(macResponse, encryptedDataResponse); return encryptor.decryptResponse(eciesCryptogramResponse); @@ -121,10 +121,10 @@ public static byte[] decryptBytesFromResponse(EciesEncryptor encryptor, EciesEnc */ public static EciesEncryptedRequest createEncryptedRequest(EciesCryptogram eciesCryptogram, boolean useIv) { EciesEncryptedRequest request = new EciesEncryptedRequest(); - request.setEncryptedData(BaseEncoding.base64().encode(eciesCryptogram.getEncryptedData())); - request.setEphemeralPublicKey(BaseEncoding.base64().encode(eciesCryptogram.getEphemeralPublicKey())); - request.setMac(BaseEncoding.base64().encode(eciesCryptogram.getMac())); - request.setNonce(useIv ? BaseEncoding.base64().encode(eciesCryptogram.getNonce()) : null); + request.setEncryptedData(Base64.getEncoder().encodeToString(eciesCryptogram.getEncryptedData())); + request.setEphemeralPublicKey(Base64.getEncoder().encodeToString(eciesCryptogram.getEphemeralPublicKey())); + request.setMac(Base64.getEncoder().encodeToString(eciesCryptogram.getMac())); + request.setNonce(useIv ? Base64.getEncoder().encodeToString(eciesCryptogram.getNonce()) : null); return request; } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/VerifySignatureUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/VerifySignatureUtil.java index 595e50d7..24d3db54 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/VerifySignatureUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/VerifySignatureUtil.java @@ -16,7 +16,6 @@ */ package io.getlime.security.powerauth.lib.cmd.util; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.http.PowerAuthRequestCanonizationUtils; import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; @@ -26,6 +25,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; +import java.util.Base64; /** * Help class with utils for signature verification. @@ -76,7 +76,7 @@ public static byte[] extractRequestDataBytes(VerifySignatureStepModel model, Ste "Request payload", "Data from the request payload file, used as the POST / DELETE / ... method body, encoded as Base64.", "OK", - BaseEncoding.base64().encode(requestDataBytes) + Base64.getEncoder().encode(requestDataBytes) ); } else { requestDataBytes = new byte[0]; From cec3a7d037c452b2d89fcbf0af799fd6f1557c56 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 3 Apr 2023 08:54:07 +0200 Subject: [PATCH 13/53] Fix #294: Coverity: Null pointer dereferences --- .../security/powerauth/lib/cmd/util/CounterUtil.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java index 772bd0b9..eaa69860 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java @@ -21,6 +21,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.model.BaseStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.data.BaseStepData; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; +import org.springframework.util.Assert; import java.nio.ByteBuffer; import java.util.Base64; @@ -102,9 +103,10 @@ public static void incrementCounter(BaseStepData model) { if (version == 3) { String ctrDataBase64 = resultStatusObject.getCtrData(); if (!ctrDataBase64.isEmpty()) { - byte[] ctrData = Base64.getDecoder().decode(ctrDataBase64); - ctrData = new HashBasedCounter().next(ctrData); - resultStatusObject.setCtrData(Base64.getEncoder().encodeToString(ctrData)); + final byte[] ctrData = Base64.getDecoder().decode(ctrDataBase64); + final byte[] nextCrtData = new HashBasedCounter().next(ctrData); + Assert.state(nextCrtData != null, "nextCrtData must not be null"); + resultStatusObject.setCtrData(Base64.getEncoder().encodeToString(nextCrtData)); } } } From a293352d1052b87a7904e09077f19a4b34b28d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Fri, 14 Apr 2023 11:12:18 +0200 Subject: [PATCH 14/53] Fix #296: Migrate to Spring Boot 3 (#297) --- docs/Readme.md | 5 ++--- pom.xml | 6 +++--- .../powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java | 2 +- .../powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/Readme.md b/docs/Readme.md index 8e0914a8..cff70efc 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -11,10 +11,9 @@ You can download the latest `powerauth-java-cmd.jar` at the releases page: ## Supported Java Runtime Versions The following Java runtime versions are supported: -- Java 8 (LTS release) -- Java 11 (LTS release) +- Java 17 (LTS release) or higher -The command-line tool application may run on other Java versions, however we do not perform extensive testing with non-LTS releases. Java version 17 is not supported yet due to issues with running Bouncy Castle provider from a fat jar. +Older Java versions are currently not supported due to migration to Spring Boot 3 ## Bouncy Castle Library Usage diff --git a/pom.xml b/pom.xml index 147cbd71..abc65c40 100644 --- a/pom.xml +++ b/pom.xml @@ -73,12 +73,12 @@ UTF-8 - 1.8 - 1.8 + 17 + 17 3.2.1 3.1.1 3.5.0 - 2.7.10 + 3.0.5 1.72 1.5.0 2.11.0 diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java index c82d28a3..4791bbaf 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java @@ -47,7 +47,7 @@ *
  • 3.0
  • *
  • 3.1
  • * - *

    + * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com * @author Roman Strobl, roman.strobl@wultra.com */ diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java index ae75904c..bbbee4e6 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java @@ -46,7 +46,7 @@ *

  • 3.0
  • *
  • 3.1
  • * - *

    + * * @author Roman Strobl, roman.strobl@wultra.com */ @Component From 0e7cb5bedc02f605436b9316ce20a85ce2081939 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 14 Apr 2023 17:03:29 +0200 Subject: [PATCH 15/53] Fix #298: Adapt changes of restful-integration --- .../lib/cmd/consts/PowerAuthConst.java | 2 +- .../lib/cmd/steps/AbstractActivationStep.java | 12 +- .../lib/cmd/steps/AbstractBaseStep.java | 4 +- .../lib/cmd/steps/v2/AbstractBaseStepV2.java | 92 ----- .../cmd/steps/v2/CreateActivationStep.java | 371 ------------------ .../lib/cmd/steps/v2/CreateTokenStep.java | 218 ---------- .../lib/cmd/steps/v2/EncryptStep.java | 197 ---------- .../lib/cmd/steps/v2/GetStatusStep.java | 167 -------- .../cmd/steps/v2/PrepareActivationStep.java | 290 -------------- .../lib/cmd/steps/v2/RemoveStep.java | 192 --------- .../lib/cmd/steps/v2/RemoveTokenStep.java | 202 ---------- .../lib/cmd/steps/v2/VaultUnlockStep.java | 265 ------------- .../cmd/steps/v3/ActivationRecoveryStep.java | 6 +- .../cmd/steps/v3/ConfirmRecoveryCodeStep.java | 6 +- .../cmd/steps/v3/CreateActivationStep.java | 6 +- .../lib/cmd/steps/v3/CreateTokenStep.java | 2 +- .../lib/cmd/steps/v3/EncryptStep.java | 2 +- .../lib/cmd/steps/v3/GetStatusStep.java | 4 +- .../cmd/steps/v3/PrepareActivationStep.java | 6 +- .../lib/cmd/steps/v3/RemoveStep.java | 2 +- .../lib/cmd/steps/v3/RemoveTokenStep.java | 4 +- .../lib/cmd/steps/v3/SignAndEncryptStep.java | 2 +- .../lib/cmd/steps/v3/StartUpgradeStep.java | 4 +- .../lib/cmd/steps/v3/TokenAndEncryptStep.java | 2 +- .../lib/cmd/steps/v3/VaultUnlockStep.java | 6 +- .../lib/cmd/util/EncryptionUtil.java | 2 +- .../powerauth/lib/cmd/util/SecurityUtil.java | 4 +- 27 files changed, 38 insertions(+), 2032 deletions(-) delete mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/AbstractBaseStepV2.java delete mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateActivationStep.java delete mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java delete mode 100755 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/EncryptStep.java delete mode 100755 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/GetStatusStep.java delete mode 100755 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/PrepareActivationStep.java delete mode 100755 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java delete mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java delete mode 100755 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthConst.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthConst.java index 0736bf35..407622e8 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthConst.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthConst.java @@ -16,7 +16,7 @@ */ package io.getlime.security.powerauth.lib.cmd.consts; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.core.ParameterizedTypeReference; import java.nio.charset.StandardCharsets; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java index 51b892ba..e246259c 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java @@ -39,12 +39,12 @@ import io.getlime.security.powerauth.lib.cmd.util.EncryptedStorageUtil; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; import io.getlime.security.powerauth.lib.cmd.util.SecurityUtil; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationLayer1Request; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationLayer2Request; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationLayer1Response; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationLayer2Response; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; +import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer2Request; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.ActivationLayer1Response; +import io.getlime.security.powerauth.rest.api.model.response.ActivationLayer2Response; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.core.ParameterizedTypeReference; import javax.crypto.SecretKey; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java index 776bd54c..d6e531ce 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java @@ -21,8 +21,8 @@ import io.getlime.security.powerauth.lib.cmd.steps.model.feature.ResultStatusChangeable; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; import io.getlime.security.powerauth.lib.cmd.util.*; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import lombok.Getter; import org.json.simple.JSONObject; import org.springframework.core.ParameterizedTypeReference; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/AbstractBaseStepV2.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/AbstractBaseStepV2.java deleted file mode 100644 index 28c76eff..00000000 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/AbstractBaseStepV2.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * PowerAuth Command-line utility - * Copyright 2021 Wultra s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.getlime.security.powerauth.lib.cmd.steps.v2; - -import com.google.common.collect.ImmutableList; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; -import io.getlime.security.powerauth.lib.cmd.logging.DisabledStepLogger; -import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; -import io.getlime.security.powerauth.lib.cmd.steps.BaseStep; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import lombok.Getter; -import org.json.simple.JSONObject; - -import java.util.List; -import java.util.Map; - -/** - * Abstract class for PowerAuth steps at version 2 - * - * @author Lukas Lukovsky, lukas.lukovsky@wultra.com - */ -public abstract class AbstractBaseStepV2 implements BaseStep { - - /** - * Default step logger - */ - protected static final StepLogger DEFAULT_STEP_LOGGER = DisabledStepLogger.INSTANCE; - - /** - * Corresponding PowerAuth step - */ - @Getter - private final PowerAuthStep step; - - /** - * Supported versions of PowerAuth - */ - @Getter - private final ImmutableList supportedVersions; - - /** - * Step logger instance - */ - protected StepLogger stepLogger; - - /** - * Constructor - * - * @param step PowerAuth step - * @param supportedVersions Supported versions of PowerAuth - * @param stepLogger Step logger instance - */ - public AbstractBaseStepV2(PowerAuthStep step, List supportedVersions, - StepLogger stepLogger) { - this.step = step; - this.supportedVersions = ImmutableList.copyOf(supportedVersions); - - this.stepLogger = stepLogger; - } - - /** - * Execute this step with given logger and context objects. - * - *

    Keeps backward compatibility with former approaches of step instantiation and execution

    - * - * @param stepLogger Step logger. - * @param context Context objects. - * @return Result status object (with current activation status), null in case of failure. - * @throws Exception In case of a failure. - */ - public final JSONObject execute(StepLogger stepLogger, Map context) throws Exception { - this.stepLogger = stepLogger != null ? stepLogger : DisabledStepLogger.INSTANCE; - ResultStatusObject resultStatusObject = execute(context); - return resultStatusObject != null ? resultStatusObject.getJsonObject() : null; - } - -} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateActivationStep.java deleted file mode 100644 index be15b0cf..00000000 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateActivationStep.java +++ /dev/null @@ -1,371 +0,0 @@ -package io.getlime.security.powerauth.lib.cmd.steps.v2; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.wultra.core.rest.client.base.RestClient; -import com.wultra.core.rest.client.base.RestClientException; -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; -import io.getlime.security.powerauth.crypto.client.encryptor.ClientNonPersonalizedEncryptor; -import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; -import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; -import io.getlime.security.powerauth.crypto.lib.encryptor.model.NonPersonalizedEncryptedMessage; -import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; -import io.getlime.security.powerauth.http.PowerAuthRequestCanonizationUtils; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; -import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; -import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.lib.cmd.util.*; -import io.getlime.security.powerauth.rest.api.model.entity.NonPersonalizedEncryptedPayloadModel; -import io.getlime.security.powerauth.rest.api.model.request.v2.ActivationCreateCustomRequest; -import io.getlime.security.powerauth.rest.api.model.request.v2.ActivationCreateRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.ActivationCreateResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; - -import javax.crypto.SecretKey; -import java.io.Console; -import java.io.FileWriter; -import java.net.URLEncoder; -import java.security.KeyPair; -import java.security.PublicKey; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Class with create activation logic. - * - *

    PowerAuth protocol versions: - *

      - *
    • 2.0
    • - *
    • 2.1
    • - *
    - * - * @author Petr Dvorak, petr@wultra.com - */ -@Component(value = "createActivationStepV2") -public class CreateActivationStep extends AbstractBaseStepV2 { - - /** - * Constructor - * @param stepLogger Step logger - */ - @Autowired - public CreateActivationStep(StepLogger stepLogger) { - super(PowerAuthStep.ACTIVATION_CREATE_CUSTOM, PowerAuthVersion.VERSION_2, stepLogger); - } - - /** - * Constructor for backward compatibility - */ - public CreateActivationStep() { - this(DEFAULT_STEP_LOGGER); - } - - private static final PowerAuthClientActivation activation = new PowerAuthClientActivation(); - private static final KeyConvertor keyConvertor = new KeyConvertor(); - private static final PowerAuthClientKeyFactory keyFactory = new PowerAuthClientKeyFactory(); - private static final KeyGenerator keyGenerator = new KeyGenerator(); - private static final PowerAuthClientVault vault = new PowerAuthClientVault(); - private static final ObjectMapper mapper = RestClientConfiguration.defaultMapper(); - - @SuppressWarnings("unchecked") - @Override - public ResultStatusObject execute(Map context) throws Exception { - // Read properties from "context" - CreateActivationStepModel model = new CreateActivationStepModel(); - model.fromMap(context); - - // Prepare the activation URI - String uri = model.getUriString(); - - // Read the identity attributes and custom attributes - Map identityAttributes = model.getIdentityAttributes(); - stepLogger.writeItem( - "activation-create-custom-identity-attributes", - "Identity Attributes", - "Following attributes are used to authenticate user", - "OK", - identityAttributes - ); - - Map customAttributes = model.getCustomAttributes(); - stepLogger.writeItem( - "activation-create-custom-custom-attributes", - "Custom Attributes", - "Following attributes are used as custom attributes for the request", - "OK", - customAttributes - ); - - // Get activation OTP, use default "zero code" in case no OTP is provided - String activationOTP = "00000-00000"; - if (model.getActivationOtp() != null) { - activationOTP = model.getActivationOtp(); - } - stepLogger.writeItem( - "activation-create-custom-activation-otp-use", - "Using activation OTP", - "Following string is used as activation OTP ('00000-00000' is used by default)'", - "OK", - activationOTP - ); - - // Build the normalized identity string - String activationIdShort = null; - for (String key : identityAttributes.keySet()) { - String value = identityAttributes.get(key); - String pair = URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(value, "UTF-8"); - if (activationIdShort == null) { - activationIdShort = pair; // initialize with the first key/value - } else { - activationIdShort = activationIdShort + "&" + pair; - } - } - if (activationIdShort != null) { - activationIdShort = PowerAuthRequestCanonizationUtils.canonizeGetParameters(activationIdShort); - if (activationIdShort == null) { - String message = "Failed to extract parameters from query string - exiting."; - stepLogger.writeError("activation-create-custom-error-query-string", message); - stepLogger.writeDoneFailed("activation-create-custom-failed"); - return null; - } - } else { - String message = "No identity attributes were provided - exiting."; - stepLogger.writeError("activation-create-custom-error-identity-attributes", message); - stepLogger.writeDoneFailed("activation-create-custom-failed"); - return null; - } - stepLogger.writeItem( - "activation-create-custom-identity-string", - "Building identity string", - "Using following normalized identity string", - "OK", - activationIdShort - ); - - // Generate device key pair and encrypt the device public key - KeyPair clientEphemeralKeyPair = keyGenerator.generateKeyPair(); - - // Generate device key pair and encrypt the device public key - KeyPair deviceKeyPair = activation.generateDeviceKeyPair(); - byte[] nonceDeviceBytes = activation.generateActivationNonce(); - byte[] cDevicePublicKeyBytes = activation.encryptDevicePublicKey( - deviceKeyPair.getPublic(), - clientEphemeralKeyPair.getPrivate(), - model.getMasterPublicKey(), - activationOTP, - activationIdShort, - nonceDeviceBytes - ); - byte[] signature = activation.computeApplicationSignature( - activationIdShort, - nonceDeviceBytes, - cDevicePublicKeyBytes, - Base64.getDecoder().decode(model.getApplicationKey()), - Base64.getDecoder().decode(model.getApplicationSecret()) - ); - byte[] ephemeralPublicKeyBytes = keyConvertor.convertPublicKeyToBytes(clientEphemeralKeyPair.getPublic()); - - // Prepare the server request - ActivationCreateRequest powerauth = new ActivationCreateRequest(); - powerauth.setActivationIdShort(activationIdShort); - powerauth.setApplicationKey(model.getApplicationKey()); - powerauth.setActivationName(model.getActivationName()); - powerauth.setActivationNonce(Base64.getEncoder().encodeToString(nonceDeviceBytes)); - powerauth.setEphemeralPublicKey(Base64.getEncoder().encodeToString(ephemeralPublicKeyBytes)); - powerauth.setEncryptedDevicePublicKey(Base64.getEncoder().encodeToString(cDevicePublicKeyBytes)); - powerauth.setApplicationSignature(Base64.getEncoder().encodeToString(signature)); - - ActivationCreateCustomRequest requestObject = new ActivationCreateCustomRequest(); - requestObject.setIdentity(identityAttributes); - requestObject.setCustomAttributes(customAttributes); - requestObject.setPowerauth(powerauth); - - stepLogger.writeItem( - "activation-create-custom-request-prepare", - "Building activation request object", - "Following activation attributes will be encrypted and sent to the server", - "OK", - requestObject - ); - - // Convert the object to bytes - byte[] requestObjectBytes = mapper.writeValueAsBytes(requestObject); - - // Prepare the encryptor - ClientNonPersonalizedEncryptor encryptor = new ClientNonPersonalizedEncryptor(Base64.getDecoder().decode(model.getApplicationKey()), model.getMasterPublicKey()); - - // Encrypt the bytes - final NonPersonalizedEncryptedMessage encryptedMessage = encryptor.encrypt(requestObjectBytes); - NonPersonalizedEncryptedPayloadModel encryptedRequestObject = new NonPersonalizedEncryptedPayloadModel(); - encryptedRequestObject.setAdHocIndex(Base64.getEncoder().encodeToString(encryptedMessage.getAdHocIndex())); - encryptedRequestObject.setApplicationKey(Base64.getEncoder().encodeToString(encryptedMessage.getApplicationKey())); - encryptedRequestObject.setEncryptedData(Base64.getEncoder().encodeToString(encryptedMessage.getEncryptedData())); - encryptedRequestObject.setEphemeralPublicKey(Base64.getEncoder().encodeToString(encryptedMessage.getEphemeralPublicKey())); - encryptedRequestObject.setMac(Base64.getEncoder().encodeToString(encryptedMessage.getMac())); - encryptedRequestObject.setMacIndex(Base64.getEncoder().encodeToString(encryptedMessage.getMacIndex())); - encryptedRequestObject.setNonce(Base64.getEncoder().encodeToString(encryptedMessage.getNonce())); - encryptedRequestObject.setSessionIndex(Base64.getEncoder().encodeToString(encryptedMessage.getSessionIndex())); - - ObjectRequest body = new ObjectRequest<>(); - body.setRequestObject(encryptedRequestObject); - - stepLogger.writeItem( - "activation-create-custom-request-encrypt", - "Encrypting request object", - "Following encrypted object is used for activation", - "OK", - body - ); - - // Call the server with activation data - try { - - Map headers = new HashMap<>(); - headers.put("Accept", "application/json"); - headers.put("Content-Type", "application/json"); - headers.putAll(model.getHeaders()); - - stepLogger.writeServerCall("activation-create-custom-request-sent", uri, "POST", requestObject, requestObjectBytes, headers); - ResponseEntity> responseEntity; - RestClient restClient = RestClientFactory.getRestClient(); - if (restClient == null) { - return null; - } - ParameterizedTypeReference> typeReference = new ParameterizedTypeReference>() { - }; - try { - responseEntity = restClient.post(uri, body, null, MapUtil.toMultiValueMap(headers), typeReference); - } catch (RestClientException ex) { - stepLogger.writeServerCallError("activation-create-custom-error-server-call", ex.getStatusCode().value(), ex.getResponse(), HttpUtil.flattenHttpHeaders(ex.getResponseHeaders())); - stepLogger.writeDoneFailed("activation-create-custom-failed"); - return null; - } - - ObjectResponse responseWrapper = Objects.requireNonNull(responseEntity.getBody()); - - stepLogger.writeServerCallOK("activation-create-custom-response-received", responseWrapper, HttpUtil.flattenHttpHeaders(responseEntity.getHeaders())); - - // Decrypt the server response - final NonPersonalizedEncryptedPayloadModel encryptedResponseObject = responseWrapper.getResponseObject(); - encryptedMessage.setApplicationKey(Base64.getDecoder().decode(encryptedResponseObject.getApplicationKey())); - encryptedMessage.setAdHocIndex(Base64.getDecoder().decode(encryptedResponseObject.getAdHocIndex())); - encryptedMessage.setEphemeralPublicKey(Base64.getDecoder().decode(encryptedResponseObject.getEphemeralPublicKey())); - encryptedMessage.setEncryptedData(Base64.getDecoder().decode(encryptedResponseObject.getEncryptedData())); - encryptedMessage.setMac(Base64.getDecoder().decode(encryptedResponseObject.getMac())); - encryptedMessage.setMacIndex(Base64.getDecoder().decode(encryptedResponseObject.getMacIndex())); - encryptedMessage.setNonce(Base64.getDecoder().decode(encryptedResponseObject.getNonce())); - encryptedMessage.setSessionIndex(Base64.getDecoder().decode(encryptedResponseObject.getSessionIndex())); - byte[] originalResponseObjectBytes = encryptor.decrypt(encryptedMessage); - ActivationCreateResponse responseObject = mapper.readValue(originalResponseObjectBytes, ActivationCreateResponse.class); - - stepLogger.writeItem( - "activation-create-custom-response-decrypt", - "Decrypted response", - "Following activation data were decrypted", - "OK", - responseObject - ); - - // Process the response object - String activationId = responseObject.getActivationId(); - byte[] nonceServerBytes = Base64.getDecoder().decode(responseObject.getActivationNonce()); - byte[] cServerPubKeyBytes = Base64.getDecoder().decode(responseObject.getEncryptedServerPublicKey()); - byte[] cServerPubKeySignatureBytes = Base64.getDecoder().decode(responseObject.getEncryptedServerPublicKeySignature()); - byte[] ephemeralKeyBytes = Base64.getDecoder().decode(responseObject.getEphemeralPublicKey()); - PublicKey ephemeralPublicKey = keyConvertor.convertBytesToPublicKey(ephemeralKeyBytes); - - // Verify that the server public key signature is valid - boolean isDataSignatureValid = activation.verifyServerDataSignature(activationId, cServerPubKeyBytes, cServerPubKeySignatureBytes, model.getMasterPublicKey()); - - if (isDataSignatureValid) { - - // Decrypt the server public key - PublicKey serverPublicKey = activation.decryptServerPublicKey(cServerPubKeyBytes, deviceKeyPair.getPrivate(), ephemeralPublicKey, activationOTP, activationIdShort, nonceServerBytes); - - // Compute master secret key - SecretKey masterSecretKey = keyFactory.generateClientMasterSecretKey(deviceKeyPair.getPrivate(), serverPublicKey); - - // Derive PowerAuth keys from master secret key - SecretKey signaturePossessionSecretKey = keyFactory.generateClientSignaturePossessionKey(masterSecretKey); - SecretKey signatureKnowledgeSecretKey = keyFactory.generateClientSignatureKnowledgeKey(masterSecretKey); - SecretKey signatureBiometrySecretKey = keyFactory.generateClientSignatureBiometryKey(masterSecretKey); - SecretKey transportMasterKey = keyFactory.generateServerTransportKey(masterSecretKey); - // DO NOT EVER STORE ... - SecretKey vaultUnlockMasterKey = keyFactory.generateServerEncryptedVaultKey(masterSecretKey); - - // Encrypt the original device private key using the vault unlock key - byte[] encryptedDevicePrivateKey = vault.encryptDevicePrivateKey(deviceKeyPair.getPrivate(), vaultUnlockMasterKey); - - char[] password; - if (model.getPassword() == null) { - Console console = System.console(); - password = console.readPassword("Select a password to encrypt the knowledge related key: "); - } else { - password = model.getPassword().toCharArray(); - } - - byte[] salt = keyGenerator.generateRandomBytes(16); - byte[] cSignatureKnowledgeSecretKey = EncryptedStorageUtil.storeSignatureKnowledgeKey(password, signatureKnowledgeSecretKey, salt, keyGenerator); - - // Prepare the status object to be stored - ResultStatusObject resultStatusObject = model.getResultStatus(); - - resultStatusObject.setActivationId(activationId); - resultStatusObject.setCounter(0L); - resultStatusObject.setCtrData(null); - resultStatusObject.setEncryptedDevicePrivateKeyBytes(encryptedDevicePrivateKey); - resultStatusObject.setServerPublicKeyObject(serverPublicKey); - resultStatusObject.setSignatureBiometryKeyObject(signatureBiometrySecretKey); - resultStatusObject.setSignatureKnowledgeKeyEncryptedBytes(cSignatureKnowledgeSecretKey); - resultStatusObject.setSignatureKnowledgeKeySaltBytes(salt); - resultStatusObject.setSignaturePossessionKeyObject(signaturePossessionSecretKey); - resultStatusObject.setTransportMasterKeyObject(transportMasterKey); - resultStatusObject.setVersion(2L); - - model.setResultStatus(resultStatusObject); - - // Store the resulting status - String formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model.getResultStatus()); - try (FileWriter file = new FileWriter(model.getStatusFileName())) { - file.write(formatted); - } - - Map objectMap = new HashMap<>(); - objectMap.put("activationId", activationId); - objectMap.put("activationStatusFile", model.getStatusFileName()); - objectMap.put("activationStatusFileContent", model.getResultStatus()); - objectMap.put("deviceKeyFingerprint", activation.computeActivationFingerprint(deviceKeyPair.getPublic())); - - stepLogger.writeItem( - "activation-create-custom-activation-done", - "Activation Done", - "Public key exchange was successfully completed, commit the activation on server if required", - "OK", - objectMap - ); - stepLogger.writeDoneOK("activation-create-custom-success"); - - return model.getResultStatus(); - } else { - String message = "Activation data signature does not match. Either someone tried to spoof your connection, or your device master key is invalid."; - stepLogger.writeError("activation-create-custom-error-signature-data", message); - stepLogger.writeDoneFailed("activation-create-custom-failed"); - return null; - } - } catch (Exception exception) { - stepLogger.writeError("activation-create-custom-error-generic", exception); - stepLogger.writeDoneFailed("activation-create-custom-failed"); - return null; - } - } - -} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java deleted file mode 100644 index 75e941a9..00000000 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/CreateTokenStep.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * PowerAuth Command-line utility - * Copyright 2018 Wultra s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.getlime.security.powerauth.lib.cmd.steps.v2; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.wultra.core.rest.client.base.RestClient; -import com.wultra.core.rest.client.base.RestClientException; -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; -import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesCryptogram; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; -import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.http.PowerAuthHttpBody; -import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; -import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; -import io.getlime.security.powerauth.lib.cmd.steps.model.CreateTokenStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.lib.cmd.util.*; -import io.getlime.security.powerauth.rest.api.model.entity.TokenResponsePayload; -import io.getlime.security.powerauth.rest.api.model.request.v2.TokenCreateRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.TokenCreateResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; - -import javax.crypto.SecretKey; -import java.io.Console; -import java.io.FileWriter; -import java.nio.charset.StandardCharsets; -import java.security.interfaces.ECPublicKey; -import java.util.*; - -/** - * Helper class with token creation logic. - * - *

    PowerAuth protocol versions: - *

      - *
    • 2.0
    • - *
    • 2.1
    • - *
    - * - * @author Petr Dvorak, petr@wultra.com - */ -@Component(value = "createTokenStepV2") -public class CreateTokenStep extends AbstractBaseStepV2 { - - private static final KeyGenerator keyGenerator = new KeyGenerator(); - private static final PowerAuthClientSignature signature = new PowerAuthClientSignature(); - private static final ObjectMapper mapper = RestClientConfiguration.defaultMapper(); - - /** - * Constructor - * @param stepLogger Step logger - */ - @Autowired - public CreateTokenStep(StepLogger stepLogger) { - super(PowerAuthStep.TOKEN_CREATE, PowerAuthVersion.VERSION_2, stepLogger); - } - - /** - * Constructor for backward compatibility - */ - public CreateTokenStep() { - this(DEFAULT_STEP_LOGGER); - } - - /** - * Execute this step with given context - * - * @param context Provided context - * @return Result status object, null in case of failure. - * @throws Exception In case of any error. - */ - @SuppressWarnings("unchecked") - @Override - public ResultStatusObject execute(Map context) throws Exception { - - // Read properties from "context" - CreateTokenStepModel model = new CreateTokenStepModel(); - model.fromMap(context); - - ResultStatusObject resultStatusObject = model.getResultStatus(); - - // Get data from status - String activationId = resultStatusObject.getActivationId(); - byte[] signatureKnowledgeKeySalt = resultStatusObject.getSignatureKnowledgeKeySaltBytes(); - byte[] signatureKnowledgeKeyEncryptedBytes = resultStatusObject.getSignatureKnowledgeKeyEncryptedBytes(); - - // Ask for the password to unlock knowledge factor key - char[] password; - if (model.getPassword() == null) { - Console console = System.console(); - password = console.readPassword("Enter your password to unlock the knowledge related key: "); - } else { - password = model.getPassword().toCharArray(); - } - - // Get the signature keys - SecretKey signaturePossessionKey = resultStatusObject.getSignaturePossessionKeyObject(); - SecretKey signatureKnowledgeKey = EncryptedStorageUtil.getSignatureKnowledgeKey(password, signatureKnowledgeKeyEncryptedBytes, signatureKnowledgeKeySalt, keyGenerator); - - // Generate nonce - byte[] nonceBytes = keyGenerator.generateRandomBytes(16); - - final String uri = model.getUriString() + "/pa/token/create"; - - final EciesEncryptor encryptor = new EciesEncryptor((ECPublicKey) model.getMasterPublicKey(), null, null); - final EciesCryptogram eciesCryptogram = encryptor.encryptRequest(new byte[0], false); - // Prepare encryption request - TokenCreateRequest requestObject = new TokenCreateRequest(); - String ephemeralPublicKeyBase64 = Base64.getEncoder().encodeToString(eciesCryptogram.getEphemeralPublicKey()); - requestObject.setEphemeralPublicKey(ephemeralPublicKeyBase64); - final ObjectRequest request = new ObjectRequest<>(requestObject); - - final byte[] requestBytes = RestClientConfiguration.defaultMapper().writeValueAsBytes(request); - - - // Compute the current PowerAuth signature for possession - // and knowledge factor - String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/token/create", nonceBytes, requestBytes) + "&" + model.getApplicationSecret(); - byte[] ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); - final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); - final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); - String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), Arrays.asList(signaturePossessionKey, signatureKnowledgeKey), ctrData, signatureConfiguration); - PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), Base64.getEncoder().encodeToString(nonceBytes), model.getVersion().value()); - String httpAuthorizationHeader = header.buildHttpHeader(); - - // Increment the counter - CounterUtil.incrementCounter(model); - - // Store the activation status (updated counter) - String formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model.getResultStatus()); - try (FileWriter file = new FileWriter(model.getStatusFileName())) { - file.write(formatted); - } - - // Call the server with activation data - try { - - Map headers = new HashMap<>(); - headers.put("Accept", "application/json"); - headers.put("Content-Type", "application/json"); - headers.put(PowerAuthSignatureHttpHeader.HEADER_NAME, httpAuthorizationHeader); - headers.putAll(model.getHeaders()); - - stepLogger.writeServerCall("token-create-request-sent", uri, "POST", request.getRequestObject(), null, headers); - - ResponseEntity> responseEntity; - RestClient restClient = RestClientFactory.getRestClient(); - if (restClient == null) { - return null; - } - ParameterizedTypeReference> typeReference = new ParameterizedTypeReference>() { - }; - try { - responseEntity = restClient.post(uri, requestBytes, null, MapUtil.toMultiValueMap(headers), typeReference); - } catch (RestClientException ex) { - stepLogger.writeServerCallError("token-create-error-server-call", ex.getStatusCode().value(), ex.getResponse(), HttpUtil.flattenHttpHeaders(ex.getResponseHeaders())); - stepLogger.writeDoneFailed("token-create-failed"); - return null; - } - ObjectResponse responseWrapper = Objects.requireNonNull(responseEntity.getBody()); - - stepLogger.writeServerCallOK("token-create-response-received", responseWrapper, HttpUtil.flattenHttpHeaders(responseEntity.getHeaders())); - - final TokenCreateResponse responseObject = responseWrapper.getResponseObject(); - - byte[] macResponse = Base64.getDecoder().decode(responseObject.getMac()); - byte[] encryptedDataResponse = Base64.getDecoder().decode(responseObject.getEncryptedData()); - EciesCryptogram eciesCryptogramResponse = new EciesCryptogram(macResponse, encryptedDataResponse); - - final byte[] decryptedBytes = encryptor.decryptResponse(eciesCryptogramResponse); - - final TokenResponsePayload tokenResponsePayload = RestClientConfiguration.defaultMapper().readValue(decryptedBytes, TokenResponsePayload.class); - - Map objectMap = new HashMap<>(); - objectMap.put("tokenId", tokenResponsePayload.getTokenId()); - objectMap.put("tokenSecret", tokenResponsePayload.getTokenSecret()); - - stepLogger.writeItem( - "token-create-token-obtained", - "Token successfully obtained", - "Token was successfully generated and decrypted", - "OK", - objectMap - - ); - stepLogger.writeDoneOK("token-create-success"); - - return model.getResultStatus(); - } catch (Exception exception) { - stepLogger.writeError("token-create-error-generic", exception); - stepLogger.writeDoneFailed("token-create-failed"); - return null; - } - } - -} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/EncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/EncryptStep.java deleted file mode 100755 index 2313775a..00000000 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/EncryptStep.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * PowerAuth Command-line utility - * Copyright 2018 Wultra s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.getlime.security.powerauth.lib.cmd.steps.v2; - -import com.wultra.core.rest.client.base.RestClient; -import com.wultra.core.rest.client.base.RestClientException; -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.crypto.client.encryptor.ClientNonPersonalizedEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.model.NonPersonalizedEncryptedMessage; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; -import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; -import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.lib.cmd.util.HttpUtil; -import io.getlime.security.powerauth.lib.cmd.util.MapUtil; -import io.getlime.security.powerauth.lib.cmd.util.RestClientFactory; -import io.getlime.security.powerauth.rest.api.model.entity.NonPersonalizedEncryptedPayloadModel; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; - -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Encrypt step encrypts request data using non-personalized end-to-end encryption. - * - *

    PowerAuth protocol versions: - *

      - *
    • 2.0
    • - *
    • 2.1
    • - *
    - * - * @author Roman Strobl, roman.strobl@wultra.com - */ -@Component(value = "encryptStepV2") -public class EncryptStep extends AbstractBaseStepV2 { - - /** - * Constructor - * @param stepLogger Step logger - */ - @Autowired - public EncryptStep(StepLogger stepLogger) { - super(PowerAuthStep.ENCRYPT, PowerAuthVersion.VERSION_2, stepLogger); - } - - /** - * Constructor for backward compatibility - */ - public EncryptStep() { - this(DEFAULT_STEP_LOGGER); - } - - /** - * Execute this step with given context. - * - * @param context Provided context. - * @return Result status object, null in case of failure. - * @throws Exception In case of any error. - */ - @SuppressWarnings("unchecked") - @Override - public ResultStatusObject execute(Map context) throws Exception { - - // Read properties from "context" - EncryptStepModel model = new EncryptStepModel(); - model.fromMap(context); - - // Prepare the encryption URI - String uri = model.getUriString(); - - // Read data which needs to be encrypted - final byte[] requestDataBytes = model.getData(); - if (requestDataBytes == null) { - stepLogger.writeError("encrypt-error-data-file", "Encrypt Request Failed", "Request data for encryption was null."); - stepLogger.writeDoneFailed("encrypt-failed"); - return null; - } - // Prepare the encryptor - ClientNonPersonalizedEncryptor encryptor = new ClientNonPersonalizedEncryptor(Base64.getDecoder().decode(model.getApplicationKey()), model.getMasterPublicKey()); - - // Encrypt the request data - final NonPersonalizedEncryptedMessage encryptedMessage = encryptor.encrypt(requestDataBytes); - if (encryptedMessage == null) { - stepLogger.writeError("encrypt-error-missing-message", "Encryption failed", "Encrypted message is not available"); - stepLogger.writeDoneFailed("encrypt-failed"); - return null; - } - - NonPersonalizedEncryptedPayloadModel encryptedRequestObject = new NonPersonalizedEncryptedPayloadModel(); - encryptedRequestObject.setAdHocIndex(Base64.getEncoder().encodeToString(encryptedMessage.getAdHocIndex())); - encryptedRequestObject.setApplicationKey(Base64.getEncoder().encodeToString(encryptedMessage.getApplicationKey())); - encryptedRequestObject.setEncryptedData(Base64.getEncoder().encodeToString(encryptedMessage.getEncryptedData())); - encryptedRequestObject.setEphemeralPublicKey(Base64.getEncoder().encodeToString(encryptedMessage.getEphemeralPublicKey())); - encryptedRequestObject.setMac(Base64.getEncoder().encodeToString(encryptedMessage.getMac())); - encryptedRequestObject.setMacIndex(Base64.getEncoder().encodeToString(encryptedMessage.getMacIndex())); - encryptedRequestObject.setNonce(Base64.getEncoder().encodeToString(encryptedMessage.getNonce())); - encryptedRequestObject.setSessionIndex(Base64.getEncoder().encodeToString(encryptedMessage.getSessionIndex())); - - ObjectRequest body = new ObjectRequest<>(); - body.setRequestObject(encryptedRequestObject); - - stepLogger.writeItem( - "encrypt-request-encrypt", - "Encrypting request data", - "Following data is sent to intermediate server", - "OK", - body - ); - - try { - - Map headers = new HashMap<>(); - headers.put("Accept", "application/json"); - headers.put("Content-Type", "application/json"); - headers.putAll(model.getHeaders()); - - stepLogger.writeServerCall("encrypt-request-sent", uri, "POST", body, null, headers); - - ResponseEntity> responseEntity; - RestClient restClient = RestClientFactory.getRestClient(); - if (restClient == null) { - return null; - } - ParameterizedTypeReference> typeReference = new ParameterizedTypeReference>() { - }; - try { - responseEntity = restClient.post(uri, body, null, MapUtil.toMultiValueMap(headers), typeReference); - } catch (RestClientException ex) { - stepLogger.writeServerCallError("encrypt-error-server-call", ex.getStatusCode().value(), ex.getResponse(), HttpUtil.flattenHttpHeaders(ex.getResponseHeaders())); - stepLogger.writeDoneFailed("encrypt-failed"); - return null; - } - - ObjectResponse responseWrapper = Objects.requireNonNull(responseEntity.getBody()); - - stepLogger.writeServerCallOK("encrypt-response-received", responseWrapper, HttpUtil.flattenHttpHeaders(responseEntity.getHeaders())); - - // Decrypt the server response - final NonPersonalizedEncryptedPayloadModel encryptedResponseObject = responseWrapper.getResponseObject(); - encryptedMessage.setApplicationKey(Base64.getDecoder().decode(encryptedResponseObject.getApplicationKey())); - encryptedMessage.setAdHocIndex(Base64.getDecoder().decode(encryptedResponseObject.getAdHocIndex())); - encryptedMessage.setEphemeralPublicKey(Base64.getDecoder().decode(encryptedResponseObject.getEphemeralPublicKey())); - encryptedMessage.setEncryptedData(Base64.getDecoder().decode(encryptedResponseObject.getEncryptedData())); - encryptedMessage.setMac(Base64.getDecoder().decode(encryptedResponseObject.getMac())); - encryptedMessage.setMacIndex(Base64.getDecoder().decode(encryptedResponseObject.getMacIndex())); - encryptedMessage.setNonce(Base64.getDecoder().decode(encryptedResponseObject.getNonce())); - encryptedMessage.setSessionIndex(Base64.getDecoder().decode(encryptedResponseObject.getSessionIndex())); - - byte[] decryptedMessageBytes = encryptor.decrypt(encryptedMessage); - if (decryptedMessageBytes == null) { - stepLogger.writeError("encrypt-error-decrypt", "Decryption failed", "Decrypted message is not available"); - stepLogger.writeDoneFailed("encrypt-failed"); - return null; - } - - String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8); - model.getResultStatus().setResponseData(decryptedMessage); - - stepLogger.writeItem( - "encrypt-response-decrypt", - "Decrypted response", - "Following data were decrypted", - "OK", - decryptedMessage - ); - stepLogger.writeDoneOK("encrypt-success"); - return model.getResultStatus(); - } catch (Exception exception) { - stepLogger.writeError("encrypt-error-generic", exception); - stepLogger.writeDoneFailed("encrypt-failed"); - return null; - } - } - -} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/GetStatusStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/GetStatusStep.java deleted file mode 100755 index a2f97749..00000000 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/GetStatusStep.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * PowerAuth Command-line utility - * Copyright 2018 Wultra s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.getlime.security.powerauth.lib.cmd.steps.v2; - -import com.wultra.core.rest.client.base.RestClient; -import com.wultra.core.rest.client.base.RestClientException; -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; -import io.getlime.security.powerauth.crypto.lib.model.ActivationStatusBlobInfo; -import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; -import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; -import io.getlime.security.powerauth.lib.cmd.logging.model.ExtendedActivationStatusBlobInfo; -import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.lib.cmd.util.HttpUtil; -import io.getlime.security.powerauth.lib.cmd.util.MapUtil; -import io.getlime.security.powerauth.lib.cmd.util.RestClientFactory; -import io.getlime.security.powerauth.rest.api.model.request.v2.ActivationStatusRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.ActivationStatusResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; - -import javax.crypto.SecretKey; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Helper class with step for getting activation status. - * - *

    PowerAuth protocol versions: - *

      - *
    • 2.0
    • - *
    • 2.1
    • - *
    - * - * @author Petr Dvorak - */ -@Component(value = "getStatusStepV2") -public class GetStatusStep extends AbstractBaseStepV2 { - - private static final PowerAuthClientActivation activation = new PowerAuthClientActivation(); - private static final KeyConvertor keyConvertor = new KeyConvertor(); - - /** - * Constructor - * @param stepLogger Step logger - */ - @Autowired - public GetStatusStep(StepLogger stepLogger) { - super(PowerAuthStep.ACTIVATION_STATUS, PowerAuthVersion.VERSION_2, stepLogger); - } - - /** - * Constructor for backward compatibility - */ - public GetStatusStep() { - this(DEFAULT_STEP_LOGGER); - } - - /** - * Execute this step with given context - * - * @param context Provided context - * @return Result status object, null in case of failure. - */ - @SuppressWarnings("unchecked") - @Override - public ResultStatusObject execute(Map context) { - - // Read properties from "context" - final GetStatusStepModel model = new GetStatusStepModel(); - model.fromMap(context); - - // Prepare the activation URI - final String uri = model.getUriString() + "/pa/activation/status"; - - ResultStatusObject resultStatusObject = model.getResultStatus(); - - // Get data from status - final String activationId = resultStatusObject.getActivationId(); - final String transportMasterKeyBase64 = resultStatusObject.getTransportMasterKey(); - final SecretKey transportMasterKey = keyConvertor.convertBytesToSharedSecretKey(Base64.getDecoder().decode(transportMasterKeyBase64)); - - // Send the activation status request to the server - final ActivationStatusRequest requestObject = new ActivationStatusRequest(); - requestObject.setActivationId(activationId); - final ObjectRequest body = new ObjectRequest<>(); - body.setRequestObject(requestObject); - - try { - - final Map headers = new HashMap<>(); - headers.put("Accept", "application/json"); - headers.put("Content-Type", "application/json"); - headers.putAll(model.getHeaders()); - - stepLogger.writeServerCall("activation-status-request-sent", uri, "POST", requestObject, null, headers); - - ResponseEntity> responseEntity; - RestClient restClient = RestClientFactory.getRestClient(); - if (restClient == null) { - return null; - } - ParameterizedTypeReference> typeReference = new ParameterizedTypeReference>() { - }; - try { - responseEntity = restClient.post(uri, body, null, MapUtil.toMultiValueMap(headers), typeReference); - } catch (RestClientException ex) { - stepLogger.writeServerCallError("activation-status-error-server-call", ex.getStatusCode().value(), ex.getResponse(), HttpUtil.flattenHttpHeaders(ex.getResponseHeaders())); - stepLogger.writeDoneFailed("activation-status-failed"); - return null; - } - - ObjectResponse responseWrapper = Objects.requireNonNull(responseEntity.getBody()); - - stepLogger.writeServerCallOK("activation-status-response-received", responseWrapper, HttpUtil.flattenHttpHeaders(responseEntity.getHeaders())); - - // Process the server response - final ActivationStatusResponse responseObject = responseWrapper.getResponseObject(); - final byte[] cStatusBlob = Base64.getDecoder().decode(responseObject.getEncryptedStatusBlob()); - - // Print the results - final ActivationStatusBlobInfo statusBlobRaw = activation.getStatusFromEncryptedBlob(cStatusBlob, null, null, transportMasterKey); - final ExtendedActivationStatusBlobInfo statusBlob = ExtendedActivationStatusBlobInfo.copy(statusBlobRaw); - - final Map objectMap = new HashMap<>(); - objectMap.put("activationId", activationId); - objectMap.put("statusBlob", statusBlob); - stepLogger.writeItem( - "activation-status-obtained", - "Activation Status", - "Activation status successfully obtained", - "OK", - objectMap - ); - stepLogger.writeDoneOK("activation-status-success"); - - return model.getResultStatus(); - } catch (Exception exception) { - stepLogger.writeError("activation-status-error-generic", exception); - stepLogger.writeDoneFailed("activation-status-failed"); - return null; - } - } - -} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/PrepareActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/PrepareActivationStep.java deleted file mode 100755 index f7487ebf..00000000 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/PrepareActivationStep.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * PowerAuth Command-line utility - * Copyright 2018 Wultra s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.getlime.security.powerauth.lib.cmd.steps.v2; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.wultra.core.rest.client.base.RestClient; -import com.wultra.core.rest.client.base.RestClientException; -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; -import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; -import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; -import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; -import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; -import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.lib.cmd.util.*; -import io.getlime.security.powerauth.rest.api.model.request.v2.ActivationCreateRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.ActivationCreateResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; - -import javax.crypto.SecretKey; -import java.io.Console; -import java.io.FileWriter; -import java.security.KeyPair; -import java.security.PublicKey; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Helper class with prepare activation logic. - * - *

    PowerAuth protocol versions: - *

      - *
    • 2.0
    • - *
    • 2.1
    • - *
    - * - * @author Petr Dvorak, petr@wultra.com - */ -@Component(value = "prepareActivationStepV2") -public class PrepareActivationStep extends AbstractBaseStepV2 { - - private static final PowerAuthClientActivation activation = new PowerAuthClientActivation(); - private static final KeyConvertor keyConversion = new KeyConvertor(); - private static final PowerAuthClientKeyFactory keyFactory = new PowerAuthClientKeyFactory(); - private static final KeyGenerator keyGenerator = new KeyGenerator(); - private static final PowerAuthClientVault vault = new PowerAuthClientVault(); - private static final ObjectMapper mapper = RestClientConfiguration.defaultMapper(); - - /** - * Constructor - * @param stepLogger Step logger - */ - @Autowired - public PrepareActivationStep(StepLogger stepLogger) { - super(PowerAuthStep.ACTIVATION_CREATE, PowerAuthVersion.VERSION_2, Objects.requireNonNull(stepLogger, "stepLogger must not be null")); - } - - /** - * Constructor for backward compatibility - */ - public PrepareActivationStep() { - this(DEFAULT_STEP_LOGGER); - } - - /** - * Execute this step with given context - * - * @param context Provided context - * @return Result status object, null in case of failure. - * @throws Exception In case of any error. - */ - @SuppressWarnings("unchecked") - @Override - public ResultStatusObject execute(Map context) throws Exception { - - // Read properties from "context" - PrepareActivationStepModel model = new PrepareActivationStepModel(); - model.fromMap(context); - - // Prepare the activation URI - String uri = model.getUriString() + "/pa/activation/create"; - - // Fetch and parse the activation code - Pattern p = Pattern.compile("^[A-Z2-7]{5}-[A-Z2-7]{5}-[A-Z2-7]{5}-[A-Z2-7]{5}(#.*)?$"); - Matcher m = p.matcher(model.getActivationCode()); - if (!m.find()) { - stepLogger.writeError("activation-create-error-activation-code", "Activation failed", "Activation code has invalid format"); - stepLogger.writeDoneFailed("activation-create-failed"); - return null; - } - String activationIdShort = model.getActivationCode().substring(0, 11); - String activationOTP = model.getActivationCode().substring(12, 23); - - - Map objectMap = new HashMap<>(); - objectMap.put("activationCode", model.getActivationCode()); - objectMap.put("activationIdShort", activationIdShort); - objectMap.put("activationOtp", activationOTP); - stepLogger.writeItem( - "activation-create-activation-code-parsed", - "Activation code", - "Parsing activation code to short activation ID and activation OTP", - "OK", - objectMap - ); - - // Generate device key pair and encrypt the device public key - KeyPair clientEphemeralKeyPair = keyGenerator.generateKeyPair(); - - // Generate device key pair and encrypt the device public key - KeyPair deviceKeyPair = activation.generateDeviceKeyPair(); - byte[] nonceDeviceBytes = activation.generateActivationNonce(); - byte[] cDevicePublicKeyBytes = activation.encryptDevicePublicKey( - deviceKeyPair.getPublic(), - clientEphemeralKeyPair.getPrivate(), - model.getMasterPublicKey(), - activationOTP, - activationIdShort, - nonceDeviceBytes - ); - byte[] signature = activation.computeApplicationSignature( - activationIdShort, - nonceDeviceBytes, - cDevicePublicKeyBytes, - Base64.getDecoder().decode(model.getApplicationKey()), - Base64.getDecoder().decode(model.getApplicationSecret()) - ); - byte[] ephemeralPublicKeyBytes = keyConversion.convertPublicKeyToBytes(clientEphemeralKeyPair.getPublic()); - - // Prepare the server request - ActivationCreateRequest requestObject = new ActivationCreateRequest(); - requestObject.setActivationIdShort(activationIdShort); - requestObject.setApplicationKey(model.getApplicationKey()); - requestObject.setActivationName(model.getActivationName()); - requestObject.setActivationNonce(Base64.getEncoder().encodeToString(nonceDeviceBytes)); - requestObject.setEphemeralPublicKey(Base64.getEncoder().encodeToString(ephemeralPublicKeyBytes)); - requestObject.setEncryptedDevicePublicKey(Base64.getEncoder().encodeToString(cDevicePublicKeyBytes)); - requestObject.setApplicationSignature(Base64.getEncoder().encodeToString(signature)); - ObjectRequest body = new ObjectRequest<>(); - body.setRequestObject(requestObject); - - // Call the server with activation data - try { - - Map headers = new HashMap<>(); - headers.put("Accept", "application/json"); - headers.put("Content-Type", "application/json"); - headers.putAll(model.getHeaders()); - - stepLogger.writeServerCall("activation-create-request-sent", uri, "POST", requestObject, null, headers); - - ResponseEntity> responseEntity; - RestClient restClient = RestClientFactory.getRestClient(); - if (restClient == null) { - return null; - } - ParameterizedTypeReference> typeReference = new ParameterizedTypeReference>() { - }; - try { - responseEntity = restClient.post(uri, body, null, MapUtil.toMultiValueMap(headers), typeReference); - } catch (RestClientException ex) { - stepLogger.writeServerCallError("activation-create-error-server-call", ex.getStatusCode().value(), ex.getResponse(), HttpUtil.flattenHttpHeaders(ex.getResponseHeaders())); - stepLogger.writeDoneFailed("activation-create-failed"); - return null; - } - - ObjectResponse responseWrapper = Objects.requireNonNull(responseEntity.getBody()); - - stepLogger.writeServerCallOK("activation-create-response-received", responseWrapper, HttpUtil.flattenHttpHeaders(responseEntity.getHeaders())); - - // Process the server response - ActivationCreateResponse responseObject = responseWrapper.getResponseObject(); - String activationId = responseObject.getActivationId(); - byte[] nonceServerBytes = Base64.getDecoder().decode(responseObject.getActivationNonce()); - byte[] cServerPubKeyBytes = Base64.getDecoder().decode(responseObject.getEncryptedServerPublicKey()); - byte[] cServerPubKeySignatureBytes = Base64.getDecoder().decode(responseObject.getEncryptedServerPublicKeySignature()); - byte[] ephemeralKeyBytes = Base64.getDecoder().decode(responseObject.getEphemeralPublicKey()); - PublicKey ephemeralPublicKey = keyConversion.convertBytesToPublicKey(ephemeralKeyBytes); - - // Verify that the server public key signature is valid - boolean isDataSignatureValid = activation.verifyServerDataSignature(activationId, cServerPubKeyBytes, cServerPubKeySignatureBytes, model.getMasterPublicKey()); - - if (isDataSignatureValid) { - - // Decrypt the server public key - PublicKey serverPublicKey = activation.decryptServerPublicKey(cServerPubKeyBytes, deviceKeyPair.getPrivate(), ephemeralPublicKey, activationOTP, activationIdShort, nonceServerBytes); - - // Compute master secret key - SecretKey masterSecretKey = keyFactory.generateClientMasterSecretKey(deviceKeyPair.getPrivate(), serverPublicKey); - - // Derive PowerAuth keys from master secret key - SecretKey signaturePossessionSecretKey = keyFactory.generateClientSignaturePossessionKey(masterSecretKey); - SecretKey signatureKnowledgeSecretKey = keyFactory.generateClientSignatureKnowledgeKey(masterSecretKey); - SecretKey signatureBiometrySecretKey = keyFactory.generateClientSignatureBiometryKey(masterSecretKey); - SecretKey transportMasterKey = keyFactory.generateServerTransportKey(masterSecretKey); - // DO NOT EVER STORE ... - SecretKey vaultUnlockMasterKey = keyFactory.generateServerEncryptedVaultKey(masterSecretKey); - - // Encrypt the original device private key using the vault unlock key - byte[] encryptedDevicePrivateKey = vault.encryptDevicePrivateKey(deviceKeyPair.getPrivate(), vaultUnlockMasterKey); - - char[] password; - if (model.getPassword() == null) { - Console console = System.console(); - password = console.readPassword("Select a password to encrypt the knowledge related key: "); - } else { - password = model.getPassword().toCharArray(); - } - - byte[] salt = keyGenerator.generateRandomBytes(16); - byte[] cSignatureKnowledgeSecretKey = EncryptedStorageUtil.storeSignatureKnowledgeKey(password, signatureKnowledgeSecretKey, salt, keyGenerator); - - // Prepare the status object to be stored - ResultStatusObject resultStatus = model.getResultStatus(); - - resultStatus.setActivationId(activationId); - resultStatus.setCounter(0L); - resultStatus.setCtrData(null); - resultStatus.setEncryptedDevicePrivateKeyBytes(encryptedDevicePrivateKey); - resultStatus.setServerPublicKeyObject(serverPublicKey); - resultStatus.setSignatureBiometryKeyObject(signatureBiometrySecretKey); - resultStatus.setSignatureKnowledgeKeyEncryptedBytes(cSignatureKnowledgeSecretKey); - resultStatus.setSignatureKnowledgeKeySaltBytes(salt); - resultStatus.setSignaturePossessionKeyObject(signaturePossessionSecretKey); - resultStatus.setTransportMasterKeyObject(transportMasterKey); - resultStatus.setVersion(2L); - - // Store the resulting status - String formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model.getResultStatus()); - try (FileWriter file = new FileWriter(model.getStatusFileName())) { - file.write(formatted); - } - - objectMap = new HashMap<>(); - objectMap.put("activationId", activationId); - objectMap.put("activationStatusFile", model.getStatusFileName()); - objectMap.put("activationStatusFileContent", model.getResultStatus()); - objectMap.put("deviceKeyFingerprint", activation.computeActivationFingerprint(deviceKeyPair.getPublic())); - - stepLogger.writeItem( - "activation-create-activation-done", - "Activation Done", - "Public key exchange was successfully completed, commit the activation on server", - "OK", - objectMap - ); - stepLogger.writeDoneOK("activation-create-success"); - - return model.getResultStatus(); - - } else { - String message = "Activation data signature does not match. Either someone tried to spoof your connection, or your device master key is invalid."; - stepLogger.writeError("activation-create-activation-signature-mismatch", message); - stepLogger.writeDoneFailed("activation-create-failed"); - return null; - } - } catch (Exception exception) { - stepLogger.writeError("activation-create-error-generic", exception); - stepLogger.writeDoneFailed("activation-create-failed"); - return null; - } - } - -} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java deleted file mode 100755 index 5488ff49..00000000 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveStep.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * PowerAuth Command-line utility - * Copyright 2018 Wultra s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.getlime.security.powerauth.lib.cmd.steps.v2; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.wultra.core.rest.client.base.RestClient; -import com.wultra.core.rest.client.base.RestClientException; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; -import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; -import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.http.PowerAuthHttpBody; -import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; -import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; -import io.getlime.security.powerauth.lib.cmd.steps.model.RemoveStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.lib.cmd.util.*; -import io.getlime.security.powerauth.rest.api.model.response.v2.ActivationRemoveResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; - -import javax.crypto.SecretKey; -import java.io.Console; -import java.io.FileWriter; -import java.nio.charset.StandardCharsets; -import java.util.*; - -/** - * Helper class with activation remove logic. - * - *

    PowerAuth protocol versions: - *

      - *
    • 2.0
    • - *
    • 2.1
    • - *
    - * - * @author Petr Dvorak - */ -@Component(value = "removeStepV2") -public class RemoveStep extends AbstractBaseStepV2 { - - private static final KeyGenerator keyGenerator = new KeyGenerator(); - private static final PowerAuthClientSignature signature = new PowerAuthClientSignature(); - private static final ObjectMapper mapper = RestClientConfiguration.defaultMapper(); - - /** - * Constructor - * @param stepLogger Step logger - */ - @Autowired - public RemoveStep(StepLogger stepLogger) { - super(PowerAuthStep.ACTIVATION_REMOVE, PowerAuthVersion.VERSION_2, stepLogger); - } - - /** - * Constructor for backward compatibility - */ - public RemoveStep() { - this(DEFAULT_STEP_LOGGER); - } - - /** - * Execute this step with given context - * - * @param context Provided context - * @return Result status object, null in case of failure. - * @throws Exception In case of any error. - */ - @SuppressWarnings("unchecked") - @Override - public ResultStatusObject execute(Map context) throws Exception { - - // Read properties from "context" - RemoveStepModel model = new RemoveStepModel(); - model.fromMap(context); - - // Prepare the activation URI - String uri = model.getUriString() + "/pa/activation/remove"; - - // Get data from status - ResultStatusObject resultStatusObject = model.getResultStatus(); - String activationId = resultStatusObject.getActivationId(); - byte[] signatureKnowledgeKeySalt = resultStatusObject.getSignatureKnowledgeKeySaltBytes(); - byte[] signatureKnowledgeKeyEncryptedBytes = resultStatusObject.getSignatureKnowledgeKeyEncryptedBytes(); - - // Ask for the password to unlock knowledge factor key - char[] password; - if (model.getPassword() == null) { - Console console = System.console(); - password = console.readPassword("Enter your password to unlock the knowledge related key: "); - } else { - password = model.getPassword().toCharArray(); - } - - // Get the signature keys - SecretKey signaturePossessionKey = resultStatusObject.getSignaturePossessionKeyObject(); - SecretKey signatureKnowledgeKey = EncryptedStorageUtil.getSignatureKnowledgeKey(password, signatureKnowledgeKeyEncryptedBytes, signatureKnowledgeKeySalt, keyGenerator); - - // Generate nonce - byte[] nonceBytes = keyGenerator.generateRandomBytes(16); - - // Compute the current PowerAuth signature for possession - // and knowledge factor - String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/activation/remove", nonceBytes, null) + "&" + model.getApplicationSecret(); - byte[] ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); - final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); - final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); - String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), Arrays.asList(signaturePossessionKey, signatureKnowledgeKey), ctrData, signatureConfiguration); - PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE.toString(), Base64.getEncoder().encodeToString(nonceBytes), model.getVersion().value()); - String httpAuthorizationHeader = header.buildHttpHeader(); - - // Increment the counter - CounterUtil.incrementCounter(model); - - // Store the activation status (updated counter) - String formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model.getResultStatus()); - try (FileWriter file = new FileWriter(model.getStatusFileName())) { - file.write(formatted); - } - - // Call the server with activation data - try { - - Map headers = new HashMap<>(); - headers.put("Accept", "application/json"); - headers.put("Content-Type", "application/json"); - headers.put(PowerAuthSignatureHttpHeader.HEADER_NAME, httpAuthorizationHeader); - headers.putAll(model.getHeaders()); - - stepLogger.writeServerCall("activation-remove-request-sent", uri, "POST", null, null, headers); - - ResponseEntity> responseEntity; - RestClient restClient = RestClientFactory.getRestClient(); - if (restClient == null) { - return null; - } - ParameterizedTypeReference> typeReference = new ParameterizedTypeReference>() { - }; - try { - responseEntity = restClient.post(uri, null, null, MapUtil.toMultiValueMap(headers), typeReference); - } catch (RestClientException ex) { - stepLogger.writeServerCallError("activation-remove-error-server-callactivation-remove-error-server-call", ex.getStatusCode().value(), ex.getResponse(), HttpUtil.flattenHttpHeaders(ex.getResponseHeaders())); - stepLogger.writeDoneFailed("activation-remove-failed"); - return null; - } - - ObjectResponse responseWrapper = Objects.requireNonNull(responseEntity.getBody()); - - stepLogger.writeServerCallOK("activation-remove-response-received", responseWrapper, HttpUtil.flattenHttpHeaders(responseEntity.getHeaders())); - - Map objectMap = new HashMap<>(); - objectMap.put("activationId", activationId); - - stepLogger.writeItem( - "activation-remove-finished", - "Activation Removed", - "Activation was successfully removed from the server", - "OK", - objectMap - - ); - stepLogger.writeDoneOK("activation-remove-success"); - - return model.getResultStatus(); - } catch (Exception exception) { - stepLogger.writeError("activation-remove-error-generic", exception); - stepLogger.writeDoneFailed("activation-remove-failed"); - return null; - } - } - -} \ No newline at end of file diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java deleted file mode 100644 index 0bc93bb7..00000000 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/RemoveTokenStep.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * PowerAuth Command-line utility - * Copyright 2018 Wultra s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.getlime.security.powerauth.lib.cmd.steps.v2; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.wultra.core.rest.client.base.RestClient; -import com.wultra.core.rest.client.base.RestClientException; -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; -import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; -import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; -import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.http.PowerAuthHttpBody; -import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; -import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; -import io.getlime.security.powerauth.lib.cmd.steps.model.RemoveTokenStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.lib.cmd.util.*; -import io.getlime.security.powerauth.rest.api.model.request.v2.TokenRemoveRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.TokenRemoveResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; - -import javax.crypto.SecretKey; -import java.io.Console; -import java.io.FileWriter; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Helper class with token remove logic. - * - *

    PowerAuth protocol versions: - *

      - *
    • 2.0
    • - *
    • 2.1
    • - *
    - * - * @author Roman Strobl, roman.strobl@wultra.com - */ -@Component(value = "removeTokenStepV2") -public class RemoveTokenStep extends AbstractBaseStepV2 { - - /** - * Constructor - * @param stepLogger Step logger - */ - @Autowired - public RemoveTokenStep(StepLogger stepLogger) { - super(PowerAuthStep.TOKEN_REMOVE, PowerAuthVersion.VERSION_2, stepLogger); - } - - /** - * Constructor for backward compatibility - */ - public RemoveTokenStep() { - this(DEFAULT_STEP_LOGGER); - } - - private static final KeyGenerator keyGenerator = new KeyGenerator(); - private static final PowerAuthClientSignature signature = new PowerAuthClientSignature(); - private static final ObjectMapper mapper = RestClientConfiguration.defaultMapper(); - private static final PowerAuthClientKeyFactory keyFactory = new PowerAuthClientKeyFactory(); - - /** - * Execute this step with given context - * - * @param context Provided context - * @return Result status object, null in case of failure. - * @throws Exception In case of any error. - */ - @SuppressWarnings("unchecked") - @Override - public ResultStatusObject execute(Map context) throws Exception { - - // Read properties from "context" - RemoveTokenStepModel model = new RemoveTokenStepModel(); - model.fromMap(context); - - ResultStatusObject resultStatusObject = model.getResultStatus(); - - // Get data from status - String activationId = resultStatusObject.getActivationId(); - byte[] signatureKnowledgeKeySalt = resultStatusObject.getSignatureKnowledgeKeySaltBytes(); - byte[] signatureKnowledgeKeyEncryptedBytes = resultStatusObject.getSignatureKnowledgeKeyEncryptedBytes(); - - // Ask for the password to unlock knowledge factor key - char[] password; - if (model.getPassword() == null) { - Console console = System.console(); - password = console.readPassword("Enter your password to unlock the knowledge related key: "); - } else { - password = model.getPassword().toCharArray(); - } - - // Get the signature keys - SecretKey signaturePossessionKey = resultStatusObject.getSignaturePossessionKeyObject(); - SecretKey signatureKnowledgeKey = EncryptedStorageUtil.getSignatureKnowledgeKey(password, signatureKnowledgeKeyEncryptedBytes, signatureKnowledgeKeySalt, keyGenerator); - SecretKey signatureBiometryKey = resultStatusObject.getSignatureBiometryKeyObject(); - - // Generate nonce - byte[] nonceBytes = keyGenerator.generateRandomBytes(16); - - final String uri = model.getUriString() + "/pa/token/remove"; - - // Prepare request - TokenRemoveRequest request = new TokenRemoveRequest(); - request.setTokenId(model.getTokenId()); - ObjectRequest objectRequest = new ObjectRequest<>(request); - - final byte[] requestBytes = RestClientConfiguration.defaultMapper().writeValueAsBytes(objectRequest); - - // Compute the current PowerAuth signature for possession - // and knowledge factor - String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/token/remove", nonceBytes, requestBytes) + "&" + model.getApplicationSecret(); - byte[] ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); - final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); - final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); - String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), keyFactory.keysForSignatureType(model.getSignatureType(), signaturePossessionKey, signatureKnowledgeKey, signatureBiometryKey), ctrData, signatureConfiguration); - final PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), Base64.getEncoder().encodeToString(nonceBytes), model.getVersion().value()); - String httpAuthorizationHeader = header.buildHttpHeader(); - - // Increment the counter - CounterUtil.incrementCounter(model); - - // Store the activation status (updated counter) - String formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model.getResultStatus()); - try (FileWriter file = new FileWriter(model.getStatusFileName())) { - file.write(formatted); - } - - // Call the server with activation data - try { - - Map headers = new HashMap<>(); - headers.put("Accept", "application/json"); - headers.put("Content-Type", "application/json"); - headers.put(PowerAuthSignatureHttpHeader.HEADER_NAME, httpAuthorizationHeader); - headers.putAll(model.getHeaders()); - - stepLogger.writeServerCall("token-remove-request-sent", uri, "POST", request, requestBytes, headers); - - ResponseEntity> responseEntity; - RestClient restClient = RestClientFactory.getRestClient(); - if (restClient == null) { - return null; - } - ParameterizedTypeReference> typeReference = new ParameterizedTypeReference>() { - }; - try { - responseEntity = restClient.post(uri, requestBytes, null, MapUtil.toMultiValueMap(headers), typeReference); - } catch (RestClientException ex) { - stepLogger.writeServerCallError("token-remove-error-server-call", ex.getStatusCode().value(), ex.getResponse(), HttpUtil.flattenHttpHeaders(ex.getResponseHeaders())); - stepLogger.writeDoneFailed("token-remove-failed"); - return null; - } - ObjectResponse responseWrapper = Objects.requireNonNull(responseEntity.getBody()); - - stepLogger.writeServerCallOK("token-remove-response-received", responseWrapper, HttpUtil.flattenHttpHeaders(responseEntity.getHeaders())); - - stepLogger.writeItem( - "token-remove-finish", - "Token successfully removed", - "Token was successfully removed", - "OK", - responseWrapper.getResponseObject().getTokenId() - - ); - stepLogger.writeDoneOK("token-remove-success"); - - return model.getResultStatus(); - } catch (Exception exception) { - stepLogger.writeError("token-remove-error-generic", exception); - stepLogger.writeDoneFailed("token-remove-failed"); - return null; - } - } - -} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java deleted file mode 100755 index 26bb13d0..00000000 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v2/VaultUnlockStep.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * PowerAuth Command-line utility - * Copyright 2018 Wultra s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.getlime.security.powerauth.lib.cmd.steps.v2; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.wultra.core.rest.client.base.RestClient; -import com.wultra.core.rest.client.base.RestClientException; -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; -import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; -import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; -import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureFormat; -import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; -import io.getlime.security.powerauth.http.PowerAuthHttpBody; -import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; -import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; -import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.lib.cmd.util.*; -import io.getlime.security.powerauth.rest.api.model.request.v2.VaultUnlockRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.VaultUnlockResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; - -import javax.crypto.SecretKey; -import java.io.Console; -import java.io.FileWriter; -import java.nio.charset.StandardCharsets; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Helper class with vault unlock logic. - * - *

    PowerAuth protocol versions: - *

      - *
    • 2.0
    • - *
    • 2.1
    • - *
    - * - * @author Petr Dvorak - */ -@Component(value = "vaultUnlockStepV2") -public class VaultUnlockStep extends AbstractBaseStepV2 { - - /** - * Constructor - * @param stepLogger Step logger - */ - @Autowired - public VaultUnlockStep(StepLogger stepLogger) { - super(PowerAuthStep.VAULT_UNLOCK, PowerAuthVersion.VERSION_2, stepLogger); - } - - /** - * Constructor for backward compatibility - */ - public VaultUnlockStep() { - this(DEFAULT_STEP_LOGGER); - } - - private static final KeyConvertor keyConvertor = new KeyConvertor(); - private static final KeyGenerator keyGenerator = new KeyGenerator(); - private static final PowerAuthClientSignature signature = new PowerAuthClientSignature(); - private static final PowerAuthClientKeyFactory keyFactory = new PowerAuthClientKeyFactory(); - private static final ObjectMapper mapper = RestClientConfiguration.defaultMapper(); - - /** - * Execute this step with given context - * - * @param context Provided context - * @return Result status object, null in case of failure. - * @throws Exception In case of any error. - */ - @SuppressWarnings("unchecked") - @Override - public ResultStatusObject execute(Map context) throws Exception { - - // Read properties from "context" - VaultUnlockStepModel model = new VaultUnlockStepModel(); - model.fromMap(context); - - // Prepare the activation URI - String uri = model.getUriString() + "/pa/vault/unlock"; - - ResultStatusObject resultStatusObject = model.getResultStatus(); - - // Get data from status - String activationId = resultStatusObject.getActivationId(); - byte[] signatureKnowledgeKeySalt = resultStatusObject.getSignatureKnowledgeKeySaltBytes(); - byte[] signatureKnowledgeKeyEncryptedBytes = resultStatusObject.getSignatureKnowledgeKeyEncryptedBytes(); - byte[] transportMasterKeyBytes = Base64.getDecoder().decode(resultStatusObject.getTransportMasterKey()); - byte[] encryptedDevicePrivateKeyBytes = resultStatusObject.getEncryptedDevicePrivateKeyBytes(); - byte[] serverPublicKeyBytes = Base64.getDecoder().decode(resultStatusObject.getServerPublicKey()); - - // Ask for the password to unlock knowledge factor key - char[] password; - if (model.getPassword() == null) { - Console console = System.console(); - password = console.readPassword("Enter your password to unlock the knowledge related key: "); - } else { - password = model.getPassword().toCharArray(); - } - - // Get the signature keys - SecretKey signaturePossessionKey = resultStatusObject.getSignaturePossessionKeyObject(); - SecretKey signatureKnowledgeKey = EncryptedStorageUtil.getSignatureKnowledgeKey(password, signatureKnowledgeKeyEncryptedBytes, signatureKnowledgeKeySalt, keyGenerator); - SecretKey signatureBiometryKey = resultStatusObject.getSignatureBiometryKeyObject(); - - // Get the transport key - SecretKey transportMasterKey = keyConvertor.convertBytesToSharedSecretKey(transportMasterKeyBytes); - - // Generate nonce - byte[] nonceBytes = keyGenerator.generateRandomBytes(16); - - // Get the vault unlocked reason - String reason = model.getReason(); - - // Prepare vault unlock request - VaultUnlockRequest vaultUnlockRequest = new VaultUnlockRequest(); - vaultUnlockRequest.setReason(reason); - ObjectRequest request = new ObjectRequest<>(vaultUnlockRequest); - final byte[] requestBytes = RestClientConfiguration.defaultMapper().writeValueAsBytes(request); - - // Compute the current PowerAuth signature for possession and knowledge factor - String signatureBaseString = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/vault/unlock", nonceBytes, requestBytes) + "&" + model.getApplicationSecret(); - byte[] ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); - final PowerAuthSignatureFormat signatureFormat = PowerAuthSignatureFormat.getFormatForSignatureVersion(model.getVersion().value()); - final SignatureConfiguration signatureConfiguration = SignatureConfiguration.forFormat(signatureFormat); - String signatureValue = signature.signatureForData(signatureBaseString.getBytes(StandardCharsets.UTF_8), keyFactory.keysForSignatureType(model.getSignatureType(), signaturePossessionKey, signatureKnowledgeKey, signatureBiometryKey), ctrData, signatureConfiguration); - PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader(activationId, model.getApplicationKey(), signatureValue, model.getSignatureType().toString(), Base64.getEncoder().encodeToString(nonceBytes), model.getVersion().value()); - String httpAuthorizationHeader = header.buildHttpHeader(); - - // Increment the counter - CounterUtil.incrementCounter(model); - - // Store the activation status (updated counter) - String formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model.getResultStatus()); - try (FileWriter file = new FileWriter(model.getStatusFileName())) { - file.write(formatted); - } - - // Call the server with activation data - try { - - Map headers = new HashMap<>(); - headers.put("Accept", "application/json"); - headers.put("Content-Type", "application/json"); - headers.put(PowerAuthSignatureHttpHeader.HEADER_NAME, httpAuthorizationHeader); - headers.putAll(model.getHeaders()); - - stepLogger.writeServerCall("vault-unlock-request-sent", uri, "POST", request.getRequestObject(), null, headers); - - ResponseEntity> responseEntity; - RestClient restClient = RestClientFactory.getRestClient(); - if (restClient == null) { - return null; - } - ParameterizedTypeReference> typeReference = new ParameterizedTypeReference>() { - }; - try { - responseEntity = restClient.post(uri, requestBytes, null, MapUtil.toMultiValueMap(headers), typeReference); - } catch (RestClientException ex) { - // Increment the counter - CounterUtil.incrementCounter(model); - - // Store the activation status (updated counter) - formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model.getResultStatus()); - try (FileWriter file = new FileWriter(model.getStatusFileName())) { - file.write(formatted); - } - - stepLogger.writeServerCallError("vault-unlock-error-server-call", ex.getStatusCode().value(), ex.getResponse(), HttpUtil.flattenHttpHeaders(ex.getResponseHeaders())); - stepLogger.writeDoneFailed("vault-unlock-failed"); - return null; - } - - ObjectResponse responseWrapper = Objects.requireNonNull(responseEntity.getBody()); - - stepLogger.writeServerCallOK("vault-unlock-response-received", responseWrapper, HttpUtil.flattenHttpHeaders(responseEntity.getHeaders())); - - VaultUnlockResponse responseObject = responseWrapper.getResponseObject(); - byte[] encryptedVaultEncryptionKey = Base64.getDecoder().decode(responseObject.getEncryptedVaultEncryptionKey()); - - PowerAuthClientVault vault = new PowerAuthClientVault(); - ctrData = CounterUtil.getCtrData(model.getResultStatus(), stepLogger); - SecretKey vaultEncryptionKey = vault.decryptVaultEncryptionKey(encryptedVaultEncryptionKey, transportMasterKey, ctrData); - PrivateKey devicePrivateKey = vault.decryptDevicePrivateKey(encryptedDevicePrivateKeyBytes, vaultEncryptionKey); - PublicKey serverPublicKey = keyConvertor.convertBytesToPublicKey(serverPublicKeyBytes); - - // Increment the counter - CounterUtil.incrementCounter(model); - - // Store the activation status (updated counter) - formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model.getResultStatus()); - try (FileWriter file = new FileWriter(model.getStatusFileName())) { - file.write(formatted); - } - - SecretKey masterSecretKey = keyFactory.generateClientMasterSecretKey(devicePrivateKey, serverPublicKey); - SecretKey transportKeyDeduced = keyFactory.generateServerTransportKey(masterSecretKey); - boolean equal = transportKeyDeduced.equals(transportMasterKey); - - // Print the results - Map objectMap = new HashMap<>(); - objectMap.put("activationId", activationId); - objectMap.put("encryptedVaultEncryptionKey", Base64.getEncoder().encodeToString(encryptedVaultEncryptionKey)); - objectMap.put("transportMasterKey", Base64.getEncoder().encodeToString(keyConvertor.convertSharedSecretKeyToBytes(transportMasterKey))); - objectMap.put("vaultEncryptionKey", Base64.getEncoder().encodeToString(keyConvertor.convertSharedSecretKeyToBytes(vaultEncryptionKey))); - objectMap.put("devicePrivateKey", Base64.getEncoder().encodeToString(keyConvertor.convertPrivateKeyToBytes(devicePrivateKey))); - objectMap.put("privateKeyDecryptionSuccessful", (equal ? "true" : "false")); - - stepLogger.writeItem( - "vault-unlock-finished", - "Vault Unlocked", - "Secure vault was successfully unlocked", - "OK", - objectMap - ); - stepLogger.writeDoneOK("vault-unlock-success"); - - return model.getResultStatus(); - } catch (Exception exception) { - - // Increment the counter, second time for vault unlock - CounterUtil.incrementCounter(model); - - // Store the activation status (updated counter) - formatted = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model.getResultStatus()); - try (FileWriter file = new FileWriter(model.getStatusFileName())) { - file.write(formatted); - } - - stepLogger.writeError("vault-unlock-error-generic", exception); - stepLogger.writeDoneFailed("vault-unlock-failed"); - return null; - } - } - -} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java index e10640b3..ad84894b 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java @@ -27,9 +27,9 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.ActivationRecoveryStepModel; import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationLayer1Request; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java index f9c82c6a..218145fd 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java @@ -30,9 +30,9 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.ConfirmRecoveryCodeStepModel; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; -import io.getlime.security.powerauth.rest.api.model.request.v3.ConfirmRecoveryRequestPayload; -import io.getlime.security.powerauth.rest.api.model.response.v3.ConfirmRecoveryResponsePayload; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.request.ConfirmRecoveryRequestPayload; +import io.getlime.security.powerauth.rest.api.model.response.ConfirmRecoveryResponsePayload; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java index ac5a1a4f..bcb7049f 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java @@ -27,9 +27,9 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationLayer1Request; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java index ea621711..6ba5830d 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java @@ -31,7 +31,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateTokenStepModel; import io.getlime.security.powerauth.rest.api.model.entity.TokenResponsePayload; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java index e4f4a06a..786c521b 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java @@ -35,7 +35,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.lib.cmd.util.SecurityUtil; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java index d9c36b62..817ac56b 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java @@ -32,8 +32,8 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationStatusRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationStatusResponse; +import io.getlime.security.powerauth.rest.api.model.request.ActivationStatusRequest; +import io.getlime.security.powerauth.rest.api.model.response.ActivationStatusResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java index 080207d1..e9d4a954 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java @@ -28,9 +28,9 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationLayer1Request; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveStep.java index 00500ccd..c3c3eb79 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveStep.java @@ -27,7 +27,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.RemoveStepModel; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java index e1288603..15cb5049 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java @@ -29,8 +29,8 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.RemoveTokenStepModel; -import io.getlime.security.powerauth.rest.api.model.request.v3.TokenRemoveRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.TokenRemoveResponse; +import io.getlime.security.powerauth.rest.api.model.request.TokenRemoveRequest; +import io.getlime.security.powerauth.rest.api.model.response.TokenRemoveResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java index 4791bbaf..1db65df5 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java @@ -31,7 +31,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.lib.cmd.util.VerifySignatureUtil; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpMethod; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java index 2cb1c6bc..a3a159f6 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java @@ -29,8 +29,8 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.StartUpgradeStepModel; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.UpgradeResponsePayload; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.UpgradeResponsePayload; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java index bbbee4e6..98361a3c 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java @@ -30,7 +30,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.TokenAndEncryptStepModel; import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpMethod; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java index ebac8dab..bd3c5b31 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java @@ -33,9 +33,9 @@ import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; -import io.getlime.security.powerauth.rest.api.model.request.v3.VaultUnlockRequestPayload; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.VaultUnlockResponsePayload; +import io.getlime.security.powerauth.rest.api.model.request.VaultUnlockRequestPayload; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.VaultUnlockResponsePayload; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java index 4373a067..b2f739c7 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java @@ -21,7 +21,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.ResponseContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.context.security.SimpleSecurityContext; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import java.nio.charset.StandardCharsets; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java index 7227ea0a..0d58e6d1 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java @@ -25,8 +25,8 @@ import io.getlime.security.powerauth.crypto.lib.model.exception.GenericCryptoException; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import java.io.ByteArrayOutputStream; import java.io.IOException; From 4d09d8bae8899d215f8c6719a38b369a9ecd34e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 18:03:33 +0000 Subject: [PATCH 16/53] Bump bcprov-jdk18on from 1.72 to 1.73 Bumps [bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.72 to 1.73. - [Release notes](https://github.com/bcgit/bc-java/releases) - [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcprov-jdk18on dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index abc65c40..4f70eb17 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ 3.1.1 3.5.0 3.0.5 - 1.72 + 1.73 1.5.0 2.11.0 1.1.1 From 985cecb87d6ed14d7ae2b546dc254f2337df40f6 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 16 May 2023 07:20:16 +0200 Subject: [PATCH 17/53] Remove OWASP Dependency Check GitHub Action --- .github/workflows/owas-dependecy-check.yml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .github/workflows/owas-dependecy-check.yml diff --git a/.github/workflows/owas-dependecy-check.yml b/.github/workflows/owas-dependecy-check.yml deleted file mode 100644 index c79178b2..00000000 --- a/.github/workflows/owas-dependecy-check.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Run OWASP Dependency Check -on: - workflow_dispatch: - - push: - branches: - - 'develop' - -jobs: - owasp-check: - uses: wultra/wultra-infrastructure/.github/workflows/owasp-dependency-check.yml@develop - secrets: inherit \ No newline at end of file From 00737d5240cbf944602bc9f3a99265d39fba1356 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 16 May 2023 07:50:16 +0200 Subject: [PATCH 18/53] Fix #303: Review Java warnings - Add final modifier - Remove unnecessary semicolon - Remove declared exceptions - Replace explicit type by diamond operator <> - Use statement lambda by expression lambda - Enhance switch - Convert to record: StepError, StepItem, StepRequest, StepResponse, StepResponse, StepResult - Fix javadoc --- .../powerauth/lib/cmd/CmdLibApplication.java | 15 ++-- .../lib/cmd/consts/PersistenceType.java | 2 +- .../lib/cmd/consts/PowerAuthConst.java | 3 +- .../lib/cmd/consts/PowerAuthStep.java | 6 +- .../lib/cmd/consts/PowerAuthVersion.java | 4 +- .../lib/cmd/logging/JsonStepLogger.java | 14 ++-- .../lib/cmd/logging/ObjectStepLogger.java | 10 +-- .../lib/cmd/logging/StepLoggerFactory.java | 15 ++-- .../ExtendedActivationStatusBlobInfo.java | 28 +++----- .../lib/cmd/logging/model/StepError.java | 57 ++------------- .../lib/cmd/logging/model/StepItem.java | 69 ++----------------- .../lib/cmd/logging/model/StepRequest.java | 61 ++-------------- .../lib/cmd/logging/model/StepResponse.java | 45 ++---------- .../lib/cmd/logging/model/StepResult.java | 21 +----- .../cmd/status/ResultStatusMemoryService.java | 4 +- .../lib/cmd/steps/AbstractBaseStep.java | 3 +- .../powerauth/lib/cmd/steps/StepProvider.java | 6 +- .../lib/cmd/steps/VerifySignatureStep.java | 6 +- .../lib/cmd/steps/VerifyTokenStep.java | 5 +- .../lib/cmd/steps/v3/CommitUpgradeStep.java | 3 +- .../lib/cmd/steps/v3/EncryptStep.java | 13 ++-- .../lib/cmd/steps/v3/GetStatusStep.java | 3 +- .../lib/cmd/steps/v3/RemoveTokenStep.java | 4 +- .../powerauth/lib/cmd/util/CounterUtil.java | 11 ++- .../lib/cmd/util/VerifySignatureUtil.java | 4 +- .../powerauth/app/cmd/Application.java | 69 +++++++------------ 26 files changed, 109 insertions(+), 372 deletions(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/CmdLibApplication.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/CmdLibApplication.java index 63345fd1..d26ee875 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/CmdLibApplication.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/CmdLibApplication.java @@ -39,16 +39,11 @@ public class CmdLibApplication { */ @Bean public StepLogger stepLogger(StepLoggerConfig config) { - switch (config.getType()) { - case DISABLED: - return DisabledStepLogger.INSTANCE; - case JSON: - return new JsonStepLogger(System.out); - case OBJECT: - return new ObjectStepLogger(System.out); - default: - throw new IllegalStateException("Not supported step logger type: " + config.getType()); - } + return switch (config.getType()) { + case DISABLED -> DisabledStepLogger.INSTANCE; + case JSON -> new JsonStepLogger(System.out); + case OBJECT -> new ObjectStepLogger(System.out); + }; } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PersistenceType.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PersistenceType.java index b1759a61..bc019f86 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PersistenceType.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PersistenceType.java @@ -31,6 +31,6 @@ public enum PersistenceType { /** * Memory */ - MEMORY; + MEMORY } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthConst.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthConst.java index 407622e8..3b321f97 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthConst.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthConst.java @@ -36,7 +36,6 @@ public class PowerAuthConst { /** * Most common response type reference for version 3 */ - public static final ParameterizedTypeReference RESPONSE_TYPE_REFERENCE_V3 = - new ParameterizedTypeReference() { }; + public static final ParameterizedTypeReference RESPONSE_TYPE_REFERENCE_V3 = new ParameterizedTypeReference<>() {}; } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthStep.java index 45833dce..067804cd 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthStep.java @@ -160,17 +160,17 @@ public enum PowerAuthStep { /** * Alias name of the step */ - String alias; + private final String alias; /** * Description of the step */ - String description; + private final String description; /** * Unique identification of the step */ - String id; + private final String id; /** * @return Alis of the step diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java index 90174a9f..6942cb51 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java @@ -70,12 +70,12 @@ public enum PowerAuthVersion { /** * Major version value */ - int majorVersion; + private final int majorVersion; /** * Version string value ("2.1", "3.0", ...) */ - String value; + private final String value; /** * Constructor diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/JsonStepLogger.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/JsonStepLogger.java index eb62e221..2085f4f6 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/JsonStepLogger.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/JsonStepLogger.java @@ -75,9 +75,10 @@ private void flush() { /** * Start the object streaming, outputs start of the JSON object: * - * // { - * // "steps" : [ - * + *
    +     * {
    +     *     "steps" : [
    +     * 
    */ @Override public void start() { try { @@ -175,9 +176,10 @@ private void flush() { /** * Closes the logger output, writes code to close the array and opened object: * - * // ] - * // } - * + *
    +     *     ]
    +     * }
    +     * 
    */ @Override public void close() { try { diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/ObjectStepLogger.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/ObjectStepLogger.java index 1c60cd68..80019c29 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/ObjectStepLogger.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/ObjectStepLogger.java @@ -103,7 +103,7 @@ public void writeServerCall(String id, String uri, String method, Object request map.put("url", uri); map.put("method", method); map.put("requestBytes", requestBytes); - map.put("requestObject", request.getRequestObject()); + map.put("requestObject", request.requestObject()); map.put("requestHeaders", headers); String name = "Sending Request"; String desc = "Calling PowerAuth Standard RESTful API endpoint"; @@ -267,7 +267,7 @@ public StepItem getFirstItem(String id) { return null; } for (StepItem item: items) { - if (id.equals(item.getId())) { + if (id.equals(item.id())) { return item; } } @@ -284,7 +284,7 @@ public StepItem getFirstItemByName(String itemName) { return null; } for (StepItem item: items) { - if (itemName.equals(item.getName())) { + if (itemName.equals(item.name())) { return item; } } @@ -309,7 +309,7 @@ public StepError getFirstError(String id) { return null; } for (StepError error: errors) { - if (id.equals(error.getId())) { + if (id.equals(error.id())) { return error; } } @@ -326,7 +326,7 @@ public StepError getFirstErrorByName(String errorName) { return null; } for (StepError error: errors) { - if (errorName.equals(error.getName())) { + if (errorName.equals(error.name())) { return error; } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/StepLoggerFactory.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/StepLoggerFactory.java index ce1d3fd0..a5814d2b 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/StepLoggerFactory.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/StepLoggerFactory.java @@ -58,16 +58,11 @@ public StepLogger createStepLogger() { return DisabledStepLogger.INSTANCE; } - switch (config.getType()) { - case DISABLED: - return DisabledStepLogger.INSTANCE; - case JSON: - return new JsonStepLogger(System.out); - case OBJECT: - return new ObjectStepLogger(System.out); - default: - throw new IllegalStateException("Unrecognized step logger type: " + config.getType()); - } + return switch (config.getType()) { + case DISABLED -> DisabledStepLogger.INSTANCE; + case JSON -> new JsonStepLogger(System.out); + case OBJECT -> new ObjectStepLogger(System.out); + }; } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/ExtendedActivationStatusBlobInfo.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/ExtendedActivationStatusBlobInfo.java index 0bd02efd..1fe8c9f6 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/ExtendedActivationStatusBlobInfo.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/ExtendedActivationStatusBlobInfo.java @@ -82,25 +82,13 @@ public String getActivationStatusName() { * @return A comprehensive displayable value. */ private String convertStatusToStatusName(byte status) { - switch (status) { - case 1: { - return "CREATED"; - } - case 2: { - return "PENDING_COMMIT"; - } - case 3: { - return "ACTIVE"; - } - case 4: { - return "BLOCKED"; - } - case 5: { - return "REMOVED"; - } - default: { - return "UNKNOWN"; - } - } + return switch (status) { + case 1 -> "CREATED"; + case 2 -> "PENDING_COMMIT"; + case 3 -> "ACTIVE"; + case 4 -> "BLOCKED"; + case 5 -> "REMOVED"; + default -> "UNKNOWN"; + }; } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepError.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepError.java index d0c4446b..55424561 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepError.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepError.java @@ -18,59 +18,12 @@ /** * Class representing an error in step. * + * @param id Error ID. + * @param name Error name. + * @param errorMessage Error message. + * @param exception Exception. * @author Roman Strobl, roman.strobl@wultra.com */ -public class StepError { +public record StepError(String id, String name, String errorMessage, Exception exception) { - private final String id; - private final String name; - private final String errorMessage; - private final Exception exception; - - /** - * Constructor with error details. - * - * @param id Error ID. - * @param name Error name. - * @param errorMessage Error message. - * @param exception Exception. - */ - public StepError(String id, String name, String errorMessage, Exception exception) { - this.id = id; - this.name = name; - this.errorMessage = errorMessage; - this.exception = exception; - } - - /** - * Get error ID. - * @return Error ID. - */ - public String getId() { - return id; - } - - /** - * Get error name. - * @return Error name. - */ - public String getName() { - return name; - } - - /** - * Get error message. - * @return Error message. - */ - public String getErrorMessage() { - return errorMessage; - } - - /** - * Get exception. - * @return Exception. - */ - public Exception getException() { - return exception; - } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepItem.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepItem.java index f91b0c54..9d1869e7 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepItem.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepItem.java @@ -18,70 +18,13 @@ /** * Class representing a generic item in step. * + * @param id Identifier of the item. + * @param name Item name. + * @param description Item description. + * @param status Status. + * @param object Related object (optional). * @author Roman Strobl, roman.strobl@wultra.com */ -public class StepItem { +public record StepItem(String id, String name, String description, String status, Object object) { - private final String id; - private final String name; - private final String description; - private final String status; - private final Object object; - - /** - * Constructor with all details. - * - * @param id Identifier of the item. - * @param name Item name. - * @param description Item description. - * @param status Status. - * @param object Related object (optional). - */ - public StepItem(String id, String name, String description, String status, Object object) { - this.id = id; - this.name = name; - this.description = description; - this.status = status; - this.object = object; - } - - /** - * Get the item ID. - * @return Item ID. - */ - public String getId() { - return id; - } - - /** - * Get item name. - * @return Item name. - */ - public String getName() { - return name; - } - - /** - * Get item description. - * @return Item description. - */ - public String getDescription() { - return description; - } - - /** - * Get item status. - * @return Item status. - */ - public String getStatus() { - return status; - } - - /** - * Get related object (optional). - * @return Related object (optional). - */ - public Object getObject() { - return object; - } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepRequest.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepRequest.java index 913827f0..c803173b 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepRequest.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepRequest.java @@ -15,68 +15,17 @@ */ package io.getlime.security.powerauth.lib.cmd.logging.model; -import io.getlime.core.rest.model.base.request.ObjectRequest; - import java.util.Map; /** * Class representing a request sent to intermediate server. * + * @param uri Request URI. + * @param method Request HTTP method. + * @param requestObject Request object. + * @param headers Request HTTP headers. * @author Roman Strobl, roman.strobl@wultra.com */ -public class StepRequest { - - private final String uri; - private final String method; - private final Object requestObject; - private final Map headers; - - /** - * Constructor with request details. - * @param uri Request URI. - * @param method Request HTTP method. - * @param requestObject Request object. - * @param headers Request HTTP headers. - */ - public StepRequest(String uri, String method, Object requestObject, Map headers) { - this.uri = uri; - this.method = method; - this.requestObject = requestObject; - this.headers = headers; - } - - /** - * Get request URI. - * @return Request URI. - */ - public String getUri() { - return uri; - } - - /** - * Get request HTTP method. - * @return Request HTTP method. - */ - public String getMethod() { - return method; - } - - /** - * Get request object. - * @return Request object. - */ - public Object getRequestObject() { - if (requestObject instanceof ObjectRequest) { - return ((ObjectRequest) requestObject).getRequestObject(); - } - return requestObject; - } +public record StepRequest(String uri, String method, Object requestObject, Map headers) { - /** - * Get request HTTP headers. - * @return Request HTTP headers. - */ - public Map getHeaders() { - return headers; - } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepResponse.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepResponse.java index 2cd26a83..06fe7b0e 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepResponse.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepResponse.java @@ -20,48 +20,11 @@ /** * Class representing response from intermediate server. * + * @param statusCode HTTP status code. + * @param responseObject Response object. + * @param headers HTTP headers. * @author Roman Strobl, roman.strobl@wultra.com */ -public class StepResponse { +public record StepResponse(int statusCode, Object responseObject, Map headers) { - private final int statusCode; - private final Object responseObject; - private final Map headers; - - /** - * Constructor with all details. - * - * @param statusCode HTTP status code. - * @param responseObject Response object. - * @param headers HTTP headers. - */ - public StepResponse(int statusCode, Object responseObject, Map headers) { - this.statusCode = statusCode; - this.responseObject = responseObject; - this.headers = headers; - } - - /** - * Get HTTP status code. - * @return HTTP status code. - */ - public int getStatusCode() { - return statusCode; - } - - /** - * Get response object. - * @return Response object. - */ - public Object getResponseObject() { - return responseObject; - } - - /** - * Get HTTP headers. - * @return HTTP headers. - */ - public Map getHeaders() { - return headers; - } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepResult.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepResult.java index 9d62b49a..ae6c852b 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepResult.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepResult.java @@ -17,24 +17,9 @@ /** * Class representing a step result. + * + * @param success Whether step was successful. */ -public class StepResult { - - private final boolean success; - - /** - * Constructor with step result. - * @param success Whether step was successful. - */ - public StepResult(boolean success) { - this.success = success; - } +public record StepResult(boolean success) { - /** - * Get whether step was successful. - * @return Whether step was successful. - */ - public boolean isSuccess() { - return success; - } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/status/ResultStatusMemoryService.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/status/ResultStatusMemoryService.java index 33df1b2a..91a210ef 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/status/ResultStatusMemoryService.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/status/ResultStatusMemoryService.java @@ -22,8 +22,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; -import java.io.IOException; - /** * Service for managing activation status objects based in memory * @@ -45,7 +43,7 @@ public ResultStatusMemoryService(ResultStatusMemoryHolder resultStatusMemoryHold } @Override - public void save(ResultStatusChangeable model) throws IOException { + public void save(ResultStatusChangeable model) { ResultStatusObject status = model.getResultStatus(); resultStatusMemoryHolder.put(status.getActivationId(), status); } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java index d6e531ce..7d4ffe28 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java @@ -63,7 +63,7 @@ public abstract class AbstractBaseStep implements Bas /** * Step logger */ - protected StepLoggerFactory stepLoggerFactory; + protected final StepLoggerFactory stepLoggerFactory; /** * Constructor @@ -87,7 +87,6 @@ public AbstractBaseStep(PowerAuthStep step, /** * Prepares a context for this step execution * - * * @param stepLogger Step logger * @param context Context data * @return Step context diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/StepProvider.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/StepProvider.java index 1543b51e..a3623c29 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/StepProvider.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/StepProvider.java @@ -66,10 +66,8 @@ private void registerPowerAuthSteps(List steps) { Map mappingVersion = mappingStepVersion.computeIfAbsent(step.getStep(), value -> new HashMap<>()); - step.getSupportedVersions().forEach(supportedVersion -> { - mappingVersion.put(supportedVersion, step); - }); - + step.getSupportedVersions().forEach(supportedVersion -> + mappingVersion.put(supportedVersion, step)); }); this.mappingStepVersion = mappingStepVersion; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java index 2f7fb8ca..4c71d3a0 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java @@ -52,8 +52,8 @@ @Component public class VerifySignatureStep extends AbstractBaseStep>> { - ParameterizedTypeReference>> RESPONSE_TYPE_REFERENCE = - new ParameterizedTypeReference>>() { }; + private static final ParameterizedTypeReference>> RESPONSE_TYPE_REFERENCE = + new ParameterizedTypeReference<>() {}; private final PowerAuthHeaderFactory powerAuthHeaderFactory; @@ -130,7 +130,7 @@ public void logDryRun(StepLogger stepLogger) { } @Override - public void processResponse(StepContext>> stepContext) throws Exception { + public void processResponse(StepContext>> stepContext) { stepContext.getStepLogger().writeItem( getStep().id() + "-signature-verified", "Signature verified", diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java index 126eb792..be0d7be2 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java @@ -51,8 +51,7 @@ @Component public class VerifyTokenStep extends AbstractBaseStep> { - ParameterizedTypeReference> RESPONSE_TYPE_REFERENCE = - new ParameterizedTypeReference>() { }; + private static final ParameterizedTypeReference> RESPONSE_TYPE_REFERENCE = new ParameterizedTypeReference<>() {}; private final PowerAuthHeaderFactory powerAuthHeaderFactory; @@ -157,7 +156,7 @@ public void logDryRun(StepLogger stepLogger) { } @Override - public void processResponse(StepContext> stepContext) throws Exception { + public void processResponse(StepContext> stepContext) { stepContext.getStepLogger().writeItem( getStep().id() + "-digest-verified", "Token digest verified", diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CommitUpgradeStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CommitUpgradeStep.java index 4882c791..931b89f5 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CommitUpgradeStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CommitUpgradeStep.java @@ -50,8 +50,7 @@ @Component public class CommitUpgradeStep extends AbstractBaseStep { - private static final ParameterizedTypeReference RESPONSE_TYPE_REFERENCE = - new ParameterizedTypeReference() { }; + private static final ParameterizedTypeReference RESPONSE_TYPE_REFERENCE = new ParameterizedTypeReference<>() {}; private final PowerAuthHeaderFactory powerAuthHeaderFactory; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java index 786c521b..430f31ae 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java @@ -120,27 +120,26 @@ public StepContext prepareStepContext( final EciesSharedInfo1 eciesSharedInfo1; final PowerAuthEncryptionHttpHeader header; switch (model.getScope()) { - case "application": + case "application" -> { // Prepare ECIES encryptor with sharedInfo1 = /pa/generic/application eciesSharedInfo1 = EciesSharedInfo1.APPLICATION_SCOPE_GENERIC; encryptor = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), applicationSecret, eciesSharedInfo1); header = new PowerAuthEncryptionHttpHeader(model.getApplicationKey(), model.getVersion().value()); - break; - - case "activation": + } + case "activation" -> { ResultStatusObject resultStatusObject = model.getResultStatus(); eciesSharedInfo1 = EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC; // Prepare ECIES encryptor with sharedInfo1 = /pa/generic/activation encryptor = SecurityUtil.createEncryptor(model.getApplicationSecret(), resultStatusObject, EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC); final String activationId = resultStatusObject.getActivationId(); header = new PowerAuthEncryptionHttpHeader(model.getApplicationKey(), activationId, model.getVersion().value()); - break; - - default: + } + default -> { stepLogger.writeError("encrypt-error-scope", "Encrypt Request Failed", "Unsupported encryption scope: " + model.getScope()); stepLogger.writeDoneFailed("encrypt-failed"); return null; + } } stepContext.setSecurityContext( diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java index 817ac56b..2c4fecff 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java @@ -63,8 +63,7 @@ public class GetStatusStep extends AbstractBaseStep> RESPONSE_TYPE_REFERENCE = - new ParameterizedTypeReference>() { - }; + new ParameterizedTypeReference<>() {}; private static final PowerAuthClientActivation ACTIVATION = new PowerAuthClientActivation(); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java index 15cb5049..2badbc1b 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java @@ -54,7 +54,7 @@ public class RemoveTokenStep extends AbstractBaseStep> { private static final ParameterizedTypeReference> RESPONSE_TYPE_REFERENCE = - new ParameterizedTypeReference>() { }; + new ParameterizedTypeReference<>() {}; private final PowerAuthHeaderFactory powerAuthHeaderFactory; @@ -118,7 +118,7 @@ public StepContext> pr } @Override - public void processResponse(StepContext> stepContext) throws Exception { + public void processResponse(StepContext> stepContext) { ObjectResponse responseWrapper = Objects.requireNonNull(stepContext.getResponseContext().getResponseBodyObject()); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java index eaa69860..b7f9a35e 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java @@ -60,16 +60,14 @@ public static byte[] getCtrData(ResultStatusObject resultStatusObject, StepLogge long counter = resultStatusObject.getCounter(); int version = resultStatusObject.getVersion().intValue(); switch (version) { - case 2: - ctrData = ByteBuffer.allocate(16).putLong(8, counter).array(); - break; - case 3: + case 2 -> ctrData = ByteBuffer.allocate(16).putLong(8, counter).array(); + case 3 -> { String ctrDataBase64 = resultStatusObject.getCtrData(); if (!ctrDataBase64.isEmpty()) { ctrData = Base64.getDecoder().decode(ctrDataBase64); } - break; - default: + } + default -> { if (stepLogger != null) { stepLogger.writeItem( "generic-error-version", @@ -79,6 +77,7 @@ public static byte[] getCtrData(ResultStatusObject resultStatusObject, StepLogge null ); } + } } return ctrData; } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/VerifySignatureUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/VerifySignatureUtil.java index 24d3db54..db1e41f7 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/VerifySignatureUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/VerifySignatureUtil.java @@ -21,7 +21,6 @@ import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; import org.springframework.http.HttpMethod; -import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; @@ -41,9 +40,8 @@ public class VerifySignatureUtil { * @param stepLogger Step logger. * @return Request data bytes. * @throws URISyntaxException In case URI is invalid. - * @throws IOException In case of any IO error. */ - public static byte[] extractRequestDataBytes(VerifySignatureStepModel model, StepLogger stepLogger) throws URISyntaxException, IOException { + public static byte[] extractRequestDataBytes(VerifySignatureStepModel model, StepLogger stepLogger) throws URISyntaxException { byte[] requestDataBytes; if (HttpMethod.GET.name().equals(model.getHttpMethod().toUpperCase())) { String query = new URI(model.getUriString()).getRawQuery(); diff --git a/powerauth-java-cmd/src/main/java/io/getlime/security/powerauth/app/cmd/Application.java b/powerauth-java-cmd/src/main/java/io/getlime/security/powerauth/app/cmd/Application.java index 0b9ddc84..bf919312 100755 --- a/powerauth-java-cmd/src/main/java/io/getlime/security/powerauth/app/cmd/Application.java +++ b/powerauth-java-cmd/src/main/java/io/getlime/security/powerauth/app/cmd/Application.java @@ -216,7 +216,7 @@ public static void main(String[] args) { // Execute the code for given methods switch (powerAuthStep) { - case TOKEN_CREATE: { + case TOKEN_CREATE -> { CreateTokenStepModel model = new CreateTokenStepModel(); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); @@ -231,9 +231,8 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case TOKEN_VALIDATE: { + case TOKEN_VALIDATE -> { VerifyTokenStepModel model = new VerifyTokenStepModel(); model.setTokenId(cmd.getOptionValue("T")); @@ -251,9 +250,8 @@ public static void main(String[] args) { model.setData(dataFileBytes); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case TOKEN_REMOVE: { + case TOKEN_REMOVE -> { RemoveTokenStepModel model = new RemoveTokenStepModel(); model.setTokenId(cmd.getOptionValue("T")); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); @@ -268,10 +266,8 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case ACTIVATION_CREATE: - case ACTIVATION_PREPARE: { + case ACTIVATION_CREATE, ACTIVATION_PREPARE -> { if (powerAuthStep.equals(PowerAuthStep.ACTIVATION_PREPARE)) { System.err.println("The 'prepare' step name is deprecated, use the 'create' step name instead"); powerAuthStep = PowerAuthStep.ACTIVATION_CREATE; @@ -294,9 +290,8 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case ACTIVATION_STATUS: { + case ACTIVATION_STATUS -> { GetStatusStepModel model = new GetStatusStepModel(); model.setHeaders(httpHeaders); @@ -305,9 +300,8 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case ACTIVATION_REMOVE: { + case ACTIVATION_REMOVE -> { RemoveStepModel model = new RemoveStepModel(); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); @@ -320,9 +314,8 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case SIGNATURE_VERIFY: { + case SIGNATURE_VERIFY -> { VerifySignatureStepModel model = new VerifySignatureStepModel(); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); @@ -344,9 +337,8 @@ public static void main(String[] args) { model.setData(dataFileBytes); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case VAULT_UNLOCK: { + case VAULT_UNLOCK -> { VaultUnlockStepModel model = new VaultUnlockStepModel(); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); @@ -361,16 +353,15 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case ACTIVATION_CREATE_CUSTOM: { + case ACTIVATION_CREATE_CUSTOM -> { String identityAttributesFileName = cmd.getOptionValue("I"); - Map identityAttributes = + Map identityAttributes = FileUtil.readDataFromFile(stepLogger, identityAttributesFileName, HashMap.class, "identity-attributes", "identity attributes"); String customAttributesFileName = cmd.getOptionValue("C"); - Map customAttributes = + Map customAttributes = FileUtil.readDataFromFile(stepLogger, customAttributesFileName, HashMap.class, "custom-attributes", "custom attributes"); CreateActivationStepModel model = new CreateActivationStepModel(); @@ -391,9 +382,8 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case ENCRYPT: { + case ENCRYPT -> { EncryptStepModel model = new EncryptStepModel(); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); @@ -411,9 +401,8 @@ public static void main(String[] args) { model.setData(dataFileBytes); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case SIGN_ENCRYPT: { + case SIGN_ENCRYPT -> { VerifySignatureStepModel model = new VerifySignatureStepModel(); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); @@ -433,9 +422,8 @@ public static void main(String[] args) { model.setData(dataFileBytes); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case TOKEN_ENCRYPT: { + case TOKEN_ENCRYPT -> { TokenAndEncryptStepModel model = new TokenAndEncryptStepModel(); model.setTokenId(cmd.getOptionValue("T")); model.setTokenSecret(cmd.getOptionValue("S")); @@ -454,9 +442,8 @@ public static void main(String[] args) { model.setData(dataFileBytes); stepExecutionService.execute(powerAuthStep, version, model); - break; } - case UPGRADE_START: { + case UPGRADE_START -> { StartUpgradeStepModel model = new StartUpgradeStepModel(); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); @@ -467,10 +454,8 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - - case UPGRADE_COMMIT: { + case UPGRADE_COMMIT -> { CommitUpgradeStepModel model = new CommitUpgradeStepModel(); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); @@ -481,16 +466,14 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - - case ACTIVATION_RECOVERY: { + case ACTIVATION_RECOVERY -> { String identityAttributesFileName = cmd.getOptionValue("I"); - Map identityAttributes = + Map identityAttributes = FileUtil.readDataFromFile(stepLogger, identityAttributesFileName, HashMap.class, "identity-attributes", "identity attributes"); String customAttributesFileName = cmd.getOptionValue("C"); - Map customAttributes = + Map customAttributes = FileUtil.readDataFromFile(stepLogger, customAttributesFileName, HashMap.class, "custom-attributes", "custom attributes"); ActivationRecoveryStepModel model = new ActivationRecoveryStepModel(); @@ -510,10 +493,8 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - - case RECOVERY_CONFIRM: { + case RECOVERY_CONFIRM -> { ConfirmRecoveryCodeStepModel model = new ConfirmRecoveryCodeStepModel(); model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); @@ -527,10 +508,8 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - - case SIGNATURE_OFFLINE_COMPUTE: { + case SIGNATURE_OFFLINE_COMPUTE -> { ComputeOfflineSignatureStepModel model = new ComputeOfflineSignatureStepModel(); model.setStatusFileName(statusFileName); @@ -540,13 +519,11 @@ public static void main(String[] args) { model.setVersion(version); stepExecutionService.execute(powerAuthStep, version, model); - break; } - - default: + default -> { System.err.println("Not recognized PowerAuth step: " + powerAuthStep); printPowerAuthStepsHelp(stepProvider); - break; + } } } catch (ExecutionException | PowerAuthCmdException e) { From a10e5a1958b72fc0918b9911d3266617f5e18eb5 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 18 May 2023 13:55:58 +0200 Subject: [PATCH 19/53] Fix #306: Coverity: Dereference null when reading password from console --- .../powerauth/lib/cmd/header/SignatureHeaderProvider.java | 6 ++++-- .../powerauth/lib/cmd/steps/AbstractActivationStep.java | 6 ++++-- .../lib/cmd/steps/ComputeOfflineSignatureStep.java | 4 +++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java index 0ed046d1..eb8bf432 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/SignatureHeaderProvider.java @@ -32,6 +32,7 @@ import io.getlime.security.powerauth.lib.cmd.util.CounterUtil; import io.getlime.security.powerauth.lib.cmd.util.EncryptedStorageUtil; import io.getlime.security.powerauth.lib.cmd.util.HttpUtil; +import org.springframework.util.Assert; import javax.crypto.SecretKey; import java.io.Console; @@ -128,10 +129,11 @@ private SecretKey getSignatureKnowledgeKey(M mod byte[] signatureKnowledgeKeyEncryptedBytes = model.getResultStatus().getSignatureKnowledgeKeyEncryptedBytes(); // Ask for the password to unlock knowledge factor key - char[] password; + final char[] password; if (model.getPassword() == null) { - Console console = System.console(); + final Console console = System.console(); password = console.readPassword("Enter your password to unlock the knowledge related key: "); + Assert.state(password != null, "Not able to read a password from the console"); } else { password = model.getPassword().toCharArray(); } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java index e246259c..5e1eb4b6 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java @@ -46,6 +46,7 @@ import io.getlime.security.powerauth.rest.api.model.response.ActivationLayer2Response; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.util.Assert; import javax.crypto.SecretKey; import java.io.Console; @@ -191,10 +192,11 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon // Encrypt the original device private key using the vault unlock key byte[] encryptedDevicePrivateKey = VAULT.encryptDevicePrivateKey(securityContext.getDeviceKeyPair().getPrivate(), vaultUnlockMasterKey); - char[] password; + final char[] password; if (model.getPassword() == null) { - Console console = System.console(); + final Console console = System.console(); password = console.readPassword("Select a password to encrypt the knowledge related key: "); + Assert.state(password != null, "Not able to read a password from the console"); } else { password = model.getPassword().toCharArray(); } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java index f9c0132c..18e0b5bb 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java @@ -36,6 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; +import org.springframework.util.Assert; import javax.crypto.SecretKey; import java.io.Console; @@ -124,8 +125,9 @@ public StepContext prepareStepContext(St // Ask for the password to unlock knowledge factor key final char[] password; if (model.getPassword() == null) { - Console console = System.console(); + final Console console = System.console(); password = console.readPassword("Enter your password to unlock the knowledge related key: "); + Assert.state(password != null, "Not able to read a password from the console"); } else { password = model.getPassword().toCharArray(); } From 3e6ef706ffb0594ee685e1ebe5fd01b7830ff7a5 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 18 May 2023 15:11:21 +0200 Subject: [PATCH 20/53] Revert logic at StepRequest#requestObject() Issue #303 --- .../lib/cmd/logging/model/StepRequest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepRequest.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepRequest.java index c803173b..6bcb9ea3 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepRequest.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/logging/model/StepRequest.java @@ -15,6 +15,8 @@ */ package io.getlime.security.powerauth.lib.cmd.logging.model; +import io.getlime.core.rest.model.base.request.ObjectRequest; + import java.util.Map; /** @@ -28,4 +30,15 @@ */ public record StepRequest(String uri, String method, Object requestObject, Map headers) { + /** + * Get request object. + * @return Request object. + */ + @Override + public Object requestObject() { + if (requestObject instanceof ObjectRequest) { + return ((ObjectRequest) requestObject).getRequestObject(); + } + return requestObject; + } } From 46bb20f9fec637906f60244cf05596f0bc9efc75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 18:01:57 +0000 Subject: [PATCH 21/53] Bump commons-io from 2.11.0 to 2.12.0 Bumps commons-io from 2.11.0 to 2.12.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4f70eb17..079c8fa9 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ 3.0.5 1.73 1.5.0 - 2.11.0 + 2.12.0 1.1.1 1.5.0-SNAPSHOT 1.7.0-SNAPSHOT From 5a6f0ca10ea9c042b1a78d4da2576ca8130af1a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 18:02:07 +0000 Subject: [PATCH 22/53] Bump maven-source-plugin from 3.2.1 to 3.3.0 Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.2.1 to 3.3.0. - [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.2.1...maven-source-plugin-3.3.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-source-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4f70eb17..15b3804b 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ UTF-8 17 17 - 3.2.1 + 3.3.0 3.1.1 3.5.0 3.0.5 From ca32ba32d48fe2332d8e1ab00ce84f6fc34133db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 09:10:01 +0000 Subject: [PATCH 23/53] Bump spring-boot.version from 3.0.5 to 3.1.0 Bumps `spring-boot.version` from 3.0.5 to 3.1.0. Updates `spring-boot-dependencies` from 3.0.5 to 3.1.0 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.0.5...v3.1.0) Updates `spring-boot-maven-plugin` from 3.0.5 to 3.1.0 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.0.5...v3.1.0) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 43bd6471..4ff7a590 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.3.0 3.1.1 3.5.0 - 3.0.5 + 3.1.0 1.73 1.5.0 2.12.0 From 0adcfca5f37bcc58bbeeb642e30c2d7099236c31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 18:00:41 +0000 Subject: [PATCH 24/53] Bump maven-surefire-plugin from 3.0.0 to 3.1.2 Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.0.0 to 3.1.2. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.0.0...surefire-3.1.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ff7a590..fc9a8001 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 1.1.1 1.5.0-SNAPSHOT 1.7.0-SNAPSHOT - 3.0.0 + 3.1.2
    From e0a1430542a14b62b4c617cbb390dac43f3c4f1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 18:00:51 +0000 Subject: [PATCH 25/53] Bump commons-io from 2.12.0 to 2.13.0 Bumps commons-io from 2.12.0 to 2.13.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ff7a590..23c2b8ec 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ 3.1.0 1.73 1.5.0 - 2.12.0 + 2.13.0 1.1.1 1.5.0-SNAPSHOT 1.7.0-SNAPSHOT From 0d974792320b3e4cd39ea2da8b13c7903219415c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:01:31 +0000 Subject: [PATCH 26/53] Bump bcprov-jdk18on from 1.73 to 1.74 Bumps [bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.73 to 1.74. - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcprov-jdk18on dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ff7a590..489d0c66 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ 3.1.1 3.5.0 3.1.0 - 1.73 + 1.74 1.5.0 2.12.0 1.1.1 From 100a6dc9cbe88d4c44434a98401f862c627645c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 18:05:57 +0000 Subject: [PATCH 27/53] Bump spring-boot.version from 3.1.0 to 3.1.1 Bumps `spring-boot.version` from 3.1.0 to 3.1.1. Updates `spring-boot-dependencies` from 3.1.0 to 3.1.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.0...v3.1.1) Updates `spring-boot-maven-plugin` from 3.1.0 to 3.1.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.0...v3.1.1) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 489d0c66..c2aec93e 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.3.0 3.1.1 3.5.0 - 3.1.0 + 3.1.1 1.74 1.5.0 2.12.0 From aec07220ec96091335318fd5055ea83b560ed02e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 05:37:31 +0000 Subject: [PATCH 28/53] Bump bcprov-jdk18on from 1.74 to 1.75 Bumps [bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.74 to 1.75. - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcprov-jdk18on dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c2aec93e..72a65617 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ 3.1.1 3.5.0 3.1.1 - 1.74 + 1.75 1.5.0 2.12.0 1.1.1 From d776b0c6b30fe30b1793606dfab178de7bb28cd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jul 2023 05:36:19 +0000 Subject: [PATCH 29/53] Bump spring-boot.version from 3.1.1 to 3.1.2 Bumps `spring-boot.version` from 3.1.1 to 3.1.2. Updates `org.springframework.boot:spring-boot-dependencies` from 3.1.1 to 3.1.2 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.1...v3.1.2) Updates `org.springframework.boot:spring-boot-maven-plugin` from 3.1.1 to 3.1.2 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.1...v3.1.2) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 72a65617..5a3fadd4 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.3.0 3.1.1 3.5.0 - 3.1.1 + 3.1.2 1.75 1.5.0 2.12.0 From 30aa570951f59718c3c1057437a7aed54693f7a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Sun, 30 Jul 2023 00:44:41 +0200 Subject: [PATCH 30/53] Update ECIES implementation for crypto 3.2 (#317) --- .../lib/cmd/consts/PowerAuthVersion.java | 19 +++- .../lib/cmd/steps/AbstractActivationStep.java | 70 ++++++++++---- .../lib/cmd/steps/AbstractBaseStep.java | 81 +++++++++++----- .../security/ActivationSecurityContext.java | 1 + .../cmd/steps/model/data/ActivationData.java | 5 + .../cmd/steps/v3/ActivationRecoveryStep.java | 2 +- .../cmd/steps/v3/ConfirmRecoveryCodeStep.java | 13 ++- .../cmd/steps/v3/CreateActivationStep.java | 2 +- .../lib/cmd/steps/v3/CreateTokenStep.java | 14 ++- .../lib/cmd/steps/v3/EncryptStep.java | 40 +++++++- .../cmd/steps/v3/PrepareActivationStep.java | 2 +- .../lib/cmd/steps/v3/SignAndEncryptStep.java | 13 ++- .../lib/cmd/steps/v3/StartUpgradeStep.java | 14 ++- .../lib/cmd/steps/v3/TokenAndEncryptStep.java | 13 ++- .../lib/cmd/steps/v3/VaultUnlockStep.java | 13 ++- .../lib/cmd/util/EncryptionUtil.java | 35 ++++++- .../powerauth/lib/cmd/util/SecurityUtil.java | 94 ++++++++++++++----- 17 files changed, 345 insertions(+), 86 deletions(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java index 6942cb51..e68cde46 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java @@ -45,7 +45,12 @@ public enum PowerAuthVersion { /** * Version 3.1 */ - V3_1(3, "3.1"); + V3_1(3, "3.1"), + + /** + * Version 3.1 + */ + V3_2(3, "3.2"); /** * All supported versions @@ -65,7 +70,7 @@ public enum PowerAuthVersion { /** * All versions belonging to major version 3 */ - public static final ImmutableList VERSION_3 = ImmutableList.of(V3_0, V3_1); + public static final ImmutableList VERSION_3 = ImmutableList.of(V3_0, V3_1, V3_2); /** * Major version value @@ -98,6 +103,16 @@ public boolean useIv() { return majorVersion >= 3 && !V3_0.equals(this); } + /** + * Provides flag whether encryption uses timestamp. + *

    This feature is supported only for protocol V3.2+.

    + * + * @return Flag whether encryption uses timestamp + */ + public boolean useTimestamp() { + return majorVersion >= 3 && !V3_0.equals(this) && !V3_1.equals(this); + } + /** * @return Version string value */ diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java index 5e1eb4b6..8cab8cfc 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java @@ -20,11 +20,12 @@ import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesCryptogram; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.*; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; +import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -37,6 +38,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.model.data.ActivationData; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; import io.getlime.security.powerauth.lib.cmd.util.EncryptedStorageUtil; +import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; import io.getlime.security.powerauth.lib.cmd.util.SecurityUtil; import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; @@ -54,10 +56,7 @@ import java.security.KeyPair; import java.security.PublicKey; import java.security.interfaces.ECPublicKey; -import java.util.Base64; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Abstract step with common parts used in activations steps @@ -140,10 +139,25 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon ActivationSecurityContext securityContext = (ActivationSecurityContext) context.getSecurityContext(); // Read activation layer 1 response and decrypt it + byte[] ephemeralPublicKeyL1 = Base64.getDecoder().decode(encryptedResponseL1.getEphemeralPublicKey()); byte[] macL1 = Base64.getDecoder().decode(encryptedResponseL1.getMac()); byte[] encryptedDataL1 = Base64.getDecoder().decode(encryptedResponseL1.getEncryptedData()); - EciesCryptogram responseCryptogramL1 = new EciesCryptogram(macL1, encryptedDataL1); - byte[] decryptedDataL1 = securityContext.getEncryptorL1().decryptResponse(responseCryptogramL1); + byte[] nonceL1 = encryptedResponseL1.getNonce() != null ? Base64.getDecoder().decode(encryptedResponseL1.getNonce()) : null; + String applicationKey = context.getModel().getApplicationKey(); + final byte[] associatedDataL1 = context.getModel().getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), applicationKey, null) : null; + + Long timestampL1 = encryptedResponseL1.getTimestamp(); + + EciesCryptogram responseCryptogramL1 = new EciesCryptogram(ephemeralPublicKeyL1, macL1, encryptedDataL1); + EciesParameters eciesParametersL1 = new EciesParameters(nonceL1, associatedDataL1, timestampL1); + EciesPayload eciesPayloadL1 = new EciesPayload(responseCryptogramL1, eciesParametersL1); + String applicationSecret = context.getModel().getApplicationSecret(); + EciesEncryptor encryptor = securityContext.getEncryptorL1(); + EciesDecryptor eciesDecryptorL1 = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, + encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, + eciesParametersL1, responseCryptogramL1.getEphemeralPublicKey()); + + byte[] decryptedDataL1 = eciesDecryptorL1.decrypt(eciesPayloadL1); // Read activation layer 1 response from data ActivationLayer1Response responseL1 = MAPPER.readValue(decryptedDataL1, ActivationLayer1Response.class); @@ -157,10 +171,21 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon ); // Decrypt layer 2 response + byte[] ephemeralPublicKeyL2 = Base64.getDecoder().decode(responseL1.getActivationData().getEphemeralPublicKey()); byte[] macL2 = Base64.getDecoder().decode(responseL1.getActivationData().getMac()); byte[] encryptedDataL2 = Base64.getDecoder().decode(responseL1.getActivationData().getEncryptedData()); - EciesCryptogram responseCryptogramL2 = new EciesCryptogram(macL2, encryptedDataL2); - byte[] decryptedDataL2 = securityContext.getEncryptorL2().decryptResponse(responseCryptogramL2); + byte[] nonceL2 = responseL1.getActivationData().getNonce() != null ? Base64.getDecoder().decode(responseL1.getActivationData().getNonce()) : null; + final byte[] associatedDataL2 = context.getModel().getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), applicationKey, null) : null; + Long timestampL2 = responseL1.getActivationData().getTimestamp(); + + EciesCryptogram responseCryptogramL2 = new EciesCryptogram(ephemeralPublicKeyL2, macL2, encryptedDataL2); + EciesParameters eciesParametersL2 = new EciesParameters(nonceL2, associatedDataL2, timestampL2); + EciesPayload responsePayloadL2 = new EciesPayload(responseCryptogramL2, eciesParametersL2); + EciesEncryptor encryptorL2 = securityContext.getEncryptorL2(); + EciesDecryptor eciesDecryptorL2 = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, + encryptorL2.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, + eciesParametersL2, responseCryptogramL2.getEphemeralPublicKey()); + byte[] decryptedDataL2 = eciesDecryptorL2.decrypt(responsePayloadL2); // Convert activation layer 2 response from JSON to object and extract activation parameters ActivationLayer2Response responseL2 = MAPPER.readValue(decryptedDataL2, ActivationLayer2Response.class); @@ -243,16 +268,25 @@ protected ParameterizedTypeReference getResponseTypeRefe * The encrypted request is then added to the request context of this step. * * @param stepContext Step context + * @param version Protocol version * @throws Exception when an error during encryption of the request data occurred */ - protected void addEncryptedRequest(StepContext stepContext) throws Exception { + protected void addEncryptedRequest(StepContext stepContext, PowerAuthVersion version) throws Exception { M model = stepContext.getModel(); // Get activation key and secret + final byte[] applicationKey = model.getApplicationKey().getBytes(StandardCharsets.UTF_8); final byte[] applicationSecret = model.getApplicationSecret().getBytes(StandardCharsets.UTF_8); - EciesEncryptor eciesEncryptorL1 = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), applicationSecret, EciesSharedInfo1.APPLICATION_SCOPE_GENERIC); - EciesEncryptor eciesEncryptorL2 = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), applicationSecret, EciesSharedInfo1.ACTIVATION_LAYER_2); + final Long timestamp = version.useTimestamp() ? new Date().getTime() : null; + final byte[] associatedData = version.useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, version.toString(), new String(applicationKey, StandardCharsets.UTF_8), null) : null; + final byte[] nonceBytesL1 = version.useIv() ? new KeyGenerator().generateRandomBytes(16) : null; + final byte[] nonceBytesL2 = version.useIv() ? new KeyGenerator().generateRandomBytes(16) : null; + final EciesParameters eciesParametersL1 = EciesParameters.builder().nonce(nonceBytesL1).associatedData(associatedData).timestamp(timestamp).build(); + final EciesParameters eciesParametersL2 = EciesParameters.builder().nonce(nonceBytesL2).associatedData(associatedData).timestamp(timestamp).build(); + + EciesEncryptor eciesEncryptorL1 = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), applicationSecret, EciesSharedInfo1.APPLICATION_SCOPE_GENERIC, eciesParametersL1); + EciesEncryptor eciesEncryptorL2 = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), applicationSecret, EciesSharedInfo1.ACTIVATION_LAYER_2, eciesParametersL2); KeyPair deviceKeyPair = ACTIVATION.generateDeviceKeyPair(); @@ -301,12 +335,14 @@ protected void addEncryptedRequest(StepContext stepCo requestL2.setDeviceInfo(model.getDeviceInfo()); final boolean useIv = model.getVersion().useIv(); + final boolean useTimestamp = model.getVersion().useTimestamp(); // Encrypt request data using ECIES in application scope with sharedInfo1 = /pa/activation - EciesCryptogram eciesCryptogramL2 = SecurityUtil.encryptObject(securityContext.getEncryptorL2(), requestL2, useIv); + final byte[] associatedDataL2 = useTimestamp ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, version.toString(), new String(applicationKey, StandardCharsets.UTF_8), null) : null; + EciesPayload eciesPayloadL2 = SecurityUtil.encryptObject(securityContext.getEncryptorL2(), requestL2, useIv, useTimestamp, associatedDataL2); // Prepare the encrypted layer 2 request - EciesEncryptedRequest encryptedRequestL2 = SecurityUtil.createEncryptedRequest(eciesCryptogramL2, useIv); + EciesEncryptedRequest encryptedRequestL2 = SecurityUtil.createEncryptedRequest(eciesPayloadL2, useIv, useTimestamp); // Prepare activation layer 1 request which is decryptable on intermediate server ActivationLayer1Request requestL1 = prepareLayer1Request(stepContext, encryptedRequestL2); @@ -320,10 +356,10 @@ protected void addEncryptedRequest(StepContext stepCo ); // Encrypt the layer 1 request using ECIES in application scope with sharedInfo1 = /pa/generic/application - EciesCryptogram eciesCryptogramL1 = SecurityUtil.encryptObject(securityContext.getEncryptorL1(), requestL1, useIv); + EciesPayload eciesPayloadL1 = SecurityUtil.encryptObject(securityContext.getEncryptorL1(), requestL1, useIv, useTimestamp, associatedData); // Prepare the encrypted layer 1 request - EciesEncryptedRequest encryptedRequestL1 = SecurityUtil.createEncryptedRequest(eciesCryptogramL1, useIv); + EciesEncryptedRequest encryptedRequestL1 = SecurityUtil.createEncryptedRequest(eciesPayloadL1, useIv, useTimestamp); stepContext.getRequestContext().setRequestObject(encryptedRequestL1); } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java index 7d4ffe28..c97a6fd5 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java @@ -3,8 +3,12 @@ import com.google.common.collect.ImmutableList; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesCryptogram; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; @@ -25,6 +29,8 @@ import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import lombok.Getter; import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -32,6 +38,7 @@ import org.springframework.http.ResponseEntity; import javax.annotation.Nullable; +import java.nio.charset.StandardCharsets; import java.util.*; /** @@ -43,6 +50,8 @@ */ public abstract class AbstractBaseStep implements BaseStep { + private static final Logger logger = LoggerFactory.getLogger(AbstractBaseStep.class); + /** * Corresponding PowerAuth step */ @@ -65,6 +74,8 @@ public abstract class AbstractBaseStep implements Bas */ protected final StepLoggerFactory stepLoggerFactory; + private static final EciesFactory ECIES_FACTORY = new EciesFactory(); + /** * Constructor * @@ -172,16 +183,17 @@ public final JSONObject execute(StepLogger stepLogger, Map conte * @param applicationSecret Application secret * @param eciesSharedInfo Parameter sharedInfo1 * @param data Request data for the encryption + * @param associatedData Data associated with ECIES * @throws Exception when an error during encryption of the request data occurred */ - public void addEncryptedRequest(StepContext stepContext, String applicationSecret, EciesSharedInfo1 eciesSharedInfo, byte[] data) throws Exception { + public void addEncryptedRequest(StepContext stepContext, String applicationSecret, EciesSharedInfo1 eciesSharedInfo, byte[] data, byte[] associatedData) throws Exception { M model = stepContext.getModel(); SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); ResultStatusObject resultStatusObject = model.getResultStatus(); EciesEncryptor encryptor; if (securityContext == null) { - encryptor = SecurityUtil.createEncryptor(applicationSecret, resultStatusObject, eciesSharedInfo); + encryptor = SecurityUtil.createEncryptor(applicationSecret, resultStatusObject, eciesSharedInfo, stepContext.getModel().getVersion(), associatedData); stepContext.setSecurityContext( SimpleSecurityContext.builder() .encryptor(encryptor) @@ -192,9 +204,10 @@ public void addEncryptedRequest(StepContext stepContext, String applicatio } final boolean useIv = model.getVersion().useIv(); + final boolean useTimestamp = model.getVersion().useTimestamp(); - final EciesCryptogram eciesCryptogram = encryptor.encryptRequest(data, useIv); - final EciesEncryptedRequest encryptedRequest = SecurityUtil.createEncryptedRequest(eciesCryptogram, useIv); + final EciesPayload eciesPayload = encryptor.encrypt(data, useIv, true, associatedData); + final EciesEncryptedRequest encryptedRequest = SecurityUtil.createEncryptedRequest(eciesPayload, useIv, useTimestamp); stepContext.getRequestContext().setRequestObject(encryptedRequest); } @@ -205,26 +218,52 @@ public void addEncryptedRequest(StepContext stepContext, String applicatio * @param stepContext Step context * @param cls Class type of the decrypted object * @param Class of the decrypted object + * @param associatedData Data associated with ECIES * @return Decrypted object from the provided response * @throws Exception when an error during object decryption occurred */ - public T decryptResponse(StepContext stepContext, Class cls) throws Exception { - SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); - EciesEncryptor encryptor = securityContext.getEncryptor(); - EciesEncryptedResponse encryptedResponse = stepContext.getResponseContext().getResponseBodyObject(); - byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(encryptor, encryptedResponse); - final T responsePayload = RestClientConfiguration.defaultMapper().readValue(decryptedBytes, cls); - stepContext.getResponseContext().setResponsePayloadDecrypted(responsePayload); - - stepContext.getStepLogger().writeItem( - getStep().id() + "-response-decrypt", - "Decrypted Response", - "Following data were decrypted", - "OK", - responsePayload - ); + public T decryptResponse(StepContext stepContext, Class cls, EciesScope eciesScope, byte[] associatedData) throws Exception { + try { + SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); + EciesEncryptedResponse encryptedResponse = stepContext.getResponseContext().getResponseBodyObject(); + final byte[] transportMasterKeyBytes = Base64.getDecoder().decode(stepContext.getModel().getResultStatus().getTransportMasterKey()); + final byte[] nonceBytes = encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : null; + EciesParameters eciesParameters = EciesParameters.builder() + .nonce(nonceBytes) + .timestamp(encryptedResponse.getTimestamp()) + .build(); + String applicationSecret = (String) stepContext.getModel().toMap().get("APPLICATION_SECRET"); + byte[] ephemeralPublicKey = Base64.getDecoder().decode(encryptedResponse.getEphemeralPublicKey()); + EciesEncryptor encryptor = securityContext.getEncryptor(); + EciesDecryptor eciesDecryptor; + if (eciesScope == EciesScope.ACTIVATION_SCOPE) { + eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.ACTIVATION_SCOPE, + encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), transportMasterKeyBytes, + eciesParameters, ephemeralPublicKey); + } else { + eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, + encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, + eciesParameters, ephemeralPublicKey); + } + + byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(eciesDecryptor, encryptedResponse, associatedData); - return responsePayload; + final T responsePayload = RestClientConfiguration.defaultMapper().readValue(decryptedBytes, cls); + stepContext.getResponseContext().setResponsePayloadDecrypted(responsePayload); + + stepContext.getStepLogger().writeItem( + getStep().id() + "-response-decrypt", + "Decrypted Response", + "Following data were decrypted", + "OK", + responsePayload + ); + + return responsePayload; + } catch (Exception ex) { + logger.debug(ex.getMessage(), ex); + return null; + } } /** diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java index 3d0bb945..25c80ca9 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java @@ -16,6 +16,7 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.context.security; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; import lombok.Builder; import lombok.Data; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/model/data/ActivationData.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/model/data/ActivationData.java index 5589a79c..15366304 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/model/data/ActivationData.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/model/data/ActivationData.java @@ -33,6 +33,11 @@ public interface ActivationData extends ResultStatusChangeable, BaseStepData { */ String getActivationName(); + /** + * @return Application key. + */ + String getApplicationKey(); + /** * @return Application secret. */ diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java index ad84894b..68b1c8be 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java @@ -91,7 +91,7 @@ public StepContext prepareS StepContext stepContext = buildStepContext(stepLogger, model, requestContext); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); - addEncryptedRequest(stepContext); + addEncryptedRequest(stepContext, model.getVersion()); return stepContext; } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java index 218145fd..6c8f11e5 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java @@ -16,7 +16,9 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v3; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -29,6 +31,8 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.ConfirmRecoveryCodeStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.StartUpgradeStepModel; +import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; import io.getlime.security.powerauth.rest.api.model.request.ConfirmRecoveryRequestPayload; import io.getlime.security.powerauth.rest.api.model.response.ConfirmRecoveryResponsePayload; @@ -109,7 +113,9 @@ public StepContext prepare // Encrypt the request final byte[] requestBytesPayload = RestClientConfiguration.defaultMapper().writeValueAsBytes(confirmRequestPayload); - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.CONFIRM_RECOVERY_CODE, requestBytesPayload); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.CONFIRM_RECOVERY_CODE, requestBytesPayload, associatedData); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); @@ -120,7 +126,10 @@ public StepContext prepare @Override public void processResponse(StepContext stepContext) throws Exception { - final ConfirmRecoveryResponsePayload confirmResponsePayload = decryptResponse(stepContext, ConfirmRecoveryResponsePayload.class); + final ConfirmRecoveryCodeStepModel model = stepContext.getModel(); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + final ConfirmRecoveryResponsePayload confirmResponsePayload = decryptResponse(stepContext, ConfirmRecoveryResponsePayload.class, EciesScope.ACTIVATION_SCOPE, associatedData); Map objectMap = new HashMap<>(); objectMap.put("alreadyConfirmed", confirmResponsePayload.getAlreadyConfirmed()); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java index bcb7049f..b244da63 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java @@ -92,7 +92,7 @@ public StepContext prepareSte buildStepContext(stepLogger, model, requestContext); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); - addEncryptedRequest(stepContext); + addEncryptedRequest(stepContext, model.getVersion()); return stepContext; } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java index 6ba5830d..4f6bd63d 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java @@ -17,7 +17,9 @@ package io.getlime.security.powerauth.lib.cmd.steps.v3; import com.google.common.collect.ImmutableMap; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -30,12 +32,15 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateTokenStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; +import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.rest.api.model.entity.TokenResponsePayload; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; +import java.util.Base64; import java.util.Map; /** @@ -99,7 +104,9 @@ public StepContext prepareStepCont StepContext stepContext = buildStepContext(stepLogger, model, requestContext); - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.CREATE_TOKEN, PowerAuthConst.EMPTY_JSON_BYTES); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.CREATE_TOKEN, PowerAuthConst.EMPTY_JSON_BYTES, associatedData); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); @@ -110,7 +117,10 @@ public StepContext prepareStepCont @Override public void processResponse(StepContext stepContext) throws Exception { - final TokenResponsePayload tokenResponsePayload = decryptResponse(stepContext, TokenResponsePayload.class); + final CreateTokenStepModel model = stepContext.getModel(); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + final TokenResponsePayload tokenResponsePayload = decryptResponse(stepContext, TokenResponsePayload.class, EciesScope.ACTIVATION_SCOPE, associatedData); stepContext.getStepLogger().writeItem( getStep().id() + "-token-obtained", diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java index 430f31ae..1aecd29f 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java @@ -18,7 +18,12 @@ import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; +import io.getlime.security.powerauth.crypto.lib.model.exception.CryptoProviderException; +import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.http.PowerAuthEncryptionHttpHeader; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; @@ -42,6 +47,7 @@ import java.nio.charset.StandardCharsets; import java.security.interfaces.ECPublicKey; +import java.util.Date; import java.util.Map; /** @@ -60,6 +66,7 @@ public class EncryptStep extends AbstractBaseStep { private static final EciesFactory ECIES_FACTORY = new EciesFactory(); + private static final KeyGenerator KEY_GENERATOR = new KeyGenerator(); /** * Constructor @@ -123,16 +130,18 @@ public StepContext prepareStepContext( case "application" -> { // Prepare ECIES encryptor with sharedInfo1 = /pa/generic/application eciesSharedInfo1 = EciesSharedInfo1.APPLICATION_SCOPE_GENERIC; + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), null) : null; encryptor = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), - applicationSecret, eciesSharedInfo1); + applicationSecret, eciesSharedInfo1, getEciesParameters(model.getVersion(), associatedData)); header = new PowerAuthEncryptionHttpHeader(model.getApplicationKey(), model.getVersion().value()); } case "activation" -> { ResultStatusObject resultStatusObject = model.getResultStatus(); eciesSharedInfo1 = EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC; // Prepare ECIES encryptor with sharedInfo1 = /pa/generic/activation - encryptor = SecurityUtil.createEncryptor(model.getApplicationSecret(), resultStatusObject, EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC); - final String activationId = resultStatusObject.getActivationId(); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + encryptor = SecurityUtil.createEncryptor(model.getApplicationSecret(), resultStatusObject, EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, model.getVersion(), associatedData); header = new PowerAuthEncryptionHttpHeader(model.getApplicationKey(), activationId, model.getVersion().value()); } default -> { @@ -147,7 +156,10 @@ public StepContext prepareStepContext( .encryptor(encryptor) .build() ); - addEncryptedRequest(stepContext, model.getApplicationSecret(), eciesSharedInfo1, requestDataBytes); + + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + addEncryptedRequest(stepContext, model.getApplicationSecret(), eciesSharedInfo1, requestDataBytes, associatedData); String headerValue = header.buildHttpHeader(); requestContext.setAuthorizationHeader(headerValue); @@ -166,7 +178,25 @@ public StepContext prepareStepContext( @Override public void processResponse(StepContext stepContext) throws Exception { - EncryptionUtil.processEncryptedResponse(stepContext, getStep().id()); + final EncryptStepModel model = stepContext.getModel(); + final String applicationSecret = model.getApplicationSecret(); + final String activationId; + final EciesScope eciesScope; + if ("activation".equals(model.getScope())) { + eciesScope = EciesScope.ACTIVATION_SCOPE; + activationId = model.getResultStatus().getActivationId(); + } else { + eciesScope = EciesScope.APPLICATION_SCOPE; + activationId = null; + } + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(eciesScope, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + EncryptionUtil.processEncryptedResponse(stepContext, getStep().id(), applicationSecret, eciesScope, associatedData); + } + + private EciesParameters getEciesParameters(PowerAuthVersion version, byte[] associatedData) throws CryptoProviderException { + final Long timestamp = version.useTimestamp() ? new Date().getTime() : null; + final byte[] nonceBytes = version.useIv() ? KEY_GENERATOR.generateRandomBytes(16) : null; + return EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java index e9d4a954..76ea2eae 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java @@ -116,7 +116,7 @@ public StepContext prepareSt buildStepContext(stepLogger, model, requestContext); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); - addEncryptedRequest(stepContext); + addEncryptedRequest(stepContext, model.getVersion()); return stepContext; } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java index 1db65df5..b23a0c23 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java @@ -16,7 +16,9 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v3; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -28,6 +30,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.AbstractBaseStep; import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; +import io.getlime.security.powerauth.lib.cmd.steps.model.StartUpgradeStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.lib.cmd.util.VerifySignatureUtil; @@ -138,7 +141,9 @@ public StepContext prepareStep powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); // Encrypt the request - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, requestDataBytes); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, requestDataBytes, associatedData); incrementCounter(model); @@ -147,7 +152,11 @@ public StepContext prepareStep @Override public void processResponse(StepContext stepContext) throws Exception { - EncryptionUtil.processEncryptedResponse(stepContext, getStep().id()); + final VerifySignatureStepModel model = stepContext.getModel(); + final String applicationSecret = model.getApplicationSecret(); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + EncryptionUtil.processEncryptedResponse(stepContext, getStep().id(), applicationSecret, EciesScope.ACTIVATION_SCOPE, associatedData); } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java index a3a159f6..f4e54827 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java @@ -16,7 +16,9 @@ package io.getlime.security.powerauth.lib.cmd.steps.v3; import com.google.common.collect.ImmutableMap; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -29,6 +31,8 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.StartUpgradeStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; +import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.model.response.UpgradeResponsePayload; import org.springframework.beans.factory.annotation.Autowired; @@ -97,7 +101,9 @@ public StepContext prepareStepCon StepContext stepContext = buildStepContext(stepLogger, model, requestContext); - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.UPGRADE, PowerAuthConst.EMPTY_JSON_BYTES); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.UPGRADE, PowerAuthConst.EMPTY_JSON_BYTES, associatedData); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); @@ -106,8 +112,10 @@ public StepContext prepareStepCon @Override public void processResponse(StepContext stepContext) throws Exception { - StartUpgradeStepModel model = stepContext.getModel(); - final UpgradeResponsePayload responsePayload = decryptResponse(stepContext, UpgradeResponsePayload.class); + final StartUpgradeStepModel model = stepContext.getModel(); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + final UpgradeResponsePayload responsePayload = decryptResponse(stepContext, UpgradeResponsePayload.class, EciesScope.ACTIVATION_SCOPE, associatedData); // Store the activation status (updated counter) model.getResultStatus().setCtrData(responsePayload.getCtrData()); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java index 98361a3c..77d6391b 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java @@ -16,7 +16,9 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v3; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -29,6 +31,7 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.TokenAndEncryptStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; @@ -138,14 +141,20 @@ public StepContext prepareStep powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); // Encrypt the request - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, requestDataBytes); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, requestDataBytes, associatedData); return stepContext; } @Override public void processResponse(StepContext stepContext) throws Exception { - EncryptionUtil.processEncryptedResponse(stepContext, getStep().id()); + final TokenAndEncryptStepModel model = stepContext.getModel(); + final String applicationSecret = model.getApplicationSecret(); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + EncryptionUtil.processEncryptedResponse(stepContext, getStep().id(), applicationSecret, EciesScope.ACTIVATION_SCOPE, associatedData); } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java index bd3c5b31..fbb17517 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java @@ -17,7 +17,9 @@ import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; @@ -30,8 +32,10 @@ import io.getlime.security.powerauth.lib.cmd.steps.AbstractBaseStep; import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; +import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; +import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; import io.getlime.security.powerauth.rest.api.model.request.VaultUnlockRequestPayload; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; @@ -120,7 +124,9 @@ public StepContext prepareStepCont final byte[] requestBytesPayload = RestClientConfiguration.defaultMapper().writeValueAsBytes(requestPayload); - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.VAULT_UNLOCK, requestBytesPayload); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.VAULT_UNLOCK, requestBytesPayload, associatedData); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); @@ -131,7 +137,10 @@ public StepContext prepareStepCont @Override public void processResponse(StepContext stepContext) throws Exception { - final VaultUnlockResponsePayload responsePayload = decryptResponse(stepContext, VaultUnlockResponsePayload.class); + final VaultUnlockStepModel model = stepContext.getModel(); + final String activationId = model.getResultStatus().getActivationId(); + final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + final VaultUnlockResponsePayload responsePayload = decryptResponse(stepContext, VaultUnlockResponsePayload.class, EciesScope.ACTIVATION_SCOPE, associatedData); ResultStatusObject resultStatusObject = stepContext.getModel().getResultStatus(); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java index b2f739c7..0f19dbbe 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java @@ -17,13 +17,20 @@ package io.getlime.security.powerauth.lib.cmd.util; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; +import io.getlime.security.powerauth.crypto.lib.util.ByteUtils; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.context.ResponseContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.context.security.SimpleSecurityContext; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import java.nio.charset.StandardCharsets; +import java.util.Base64; /** * Utility class for ECIES encryption processing. @@ -32,16 +39,39 @@ */ public class EncryptionUtil { + private static final EciesFactory ECIES_FACTORY = new EciesFactory(); + /** * Process an encrypted response for a step. * @param stepContext Step context. * @param stepId Step identifier. * @throws Exception Thrown in case response decryption fails. */ - public static void processEncryptedResponse(StepContext stepContext, String stepId) throws Exception { + public static void processEncryptedResponse(StepContext stepContext, String stepId, String applicationSecret, EciesScope eciesScope, byte[] associatedData) throws Exception { ResponseContext responseContext = stepContext.getResponseContext(); EciesEncryptor encryptor = ((SimpleSecurityContext) stepContext.getSecurityContext()).getEncryptor(); - final byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(encryptor, responseContext.getResponseBodyObject()); + + final String nonce = responseContext.getResponseBodyObject().getNonce(); + final byte[] nonceBytes = nonce != null ? Base64.getDecoder().decode(nonce) : null; + final Long timestamp = responseContext.getResponseBodyObject().getTimestamp(); + final String ephemeralPublicKey = responseContext.getResponseBodyObject().getEphemeralPublicKey(); + final byte[] ephemeralPublicKeyBytes = Base64.getDecoder().decode(ephemeralPublicKey); + final byte[] transportMasterKeyBytes = eciesScope == EciesScope.ACTIVATION_SCOPE ? Base64.getDecoder().decode(stepContext.getModel().getResultStatus().getTransportMasterKey()) : null; + + EciesParameters eciesParameters = EciesParameters.builder().nonce(nonceBytes).timestamp(timestamp).associatedData(associatedData).build(); + + EciesDecryptor eciesDecryptor; + if (eciesScope == EciesScope.ACTIVATION_SCOPE) { + eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.ACTIVATION_SCOPE, + encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), transportMasterKeyBytes, + eciesParameters, ephemeralPublicKeyBytes); + } else { + eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, + encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, + eciesParameters, ephemeralPublicKeyBytes); + } + + final byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(eciesDecryptor, responseContext.getResponseBodyObject(), associatedData); String decryptedMessage = new String(decryptedBytes, StandardCharsets.UTF_8); stepContext.getModel().getResultStatus().setResponseData(decryptedMessage); @@ -54,4 +84,5 @@ public static void processEncryptedResponse(StepContext Date: Mon, 31 Jul 2023 17:15:46 +0000 Subject: [PATCH 31/53] Bump org.bouncycastle:bcprov-jdk18on from 1.75 to 1.76 Bumps [org.bouncycastle:bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.75 to 1.76. - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcprov-jdk18on dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5a3fadd4..b80473bc 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ 3.1.1 3.5.0 3.1.2 - 1.75 + 1.76 1.5.0 2.12.0 1.1.1 From 79e6ce8f681f6ba5de3f1ab936878e296b0289be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Tue, 1 Aug 2023 17:19:02 +0200 Subject: [PATCH 32/53] Fix #320: Nonce and ephemeral public key are ignored in protocol V3.1 responses. --- .../lib/cmd/consts/PowerAuthVersion.java | 10 +++++++ .../lib/cmd/steps/AbstractActivationStep.java | 15 +++++----- .../lib/cmd/steps/AbstractBaseStep.java | 10 ++++--- .../powerauth/lib/cmd/util/SecurityUtil.java | 28 ------------------- 4 files changed, 24 insertions(+), 39 deletions(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java index e68cde46..a29718bf 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java @@ -103,6 +103,16 @@ public boolean useIv() { return majorVersion >= 3 && !V3_0.equals(this); } + /** + * Provides flag whether decryption uses different non-zero initialization vector. + *

    This feature is supported only for protocol V3.2+.

    + * + * @return Flag whether decryption uses different non-zero initialization vector. + */ + public boolean useDifferentIvForResponse() { + return majorVersion >= 3 && V3_2.equals(this); + } + /** * Provides flag whether encryption uses timestamp. *

    This feature is supported only for protocol V3.2+.

    diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java index 8cab8cfc..c704d606 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java @@ -136,17 +136,18 @@ public void processResponse(StepContext stepContext) public ResultStatusObject processResponse(EciesEncryptedResponse encryptedResponseL1, StepContext context) throws Exception { M model = context.getModel(); - ActivationSecurityContext securityContext = (ActivationSecurityContext) context.getSecurityContext(); + final PowerAuthVersion version = model.getVersion(); + final ActivationSecurityContext securityContext = (ActivationSecurityContext) context.getSecurityContext(); // Read activation layer 1 response and decrypt it - byte[] ephemeralPublicKeyL1 = Base64.getDecoder().decode(encryptedResponseL1.getEphemeralPublicKey()); + byte[] ephemeralPublicKeyL1 = securityContext.getEncryptorL1().getEnvelopeKey().getEphemeralKeyPublic(); byte[] macL1 = Base64.getDecoder().decode(encryptedResponseL1.getMac()); byte[] encryptedDataL1 = Base64.getDecoder().decode(encryptedResponseL1.getEncryptedData()); - byte[] nonceL1 = encryptedResponseL1.getNonce() != null ? Base64.getDecoder().decode(encryptedResponseL1.getNonce()) : null; + byte[] nonceL1 = version.useDifferentIvForResponse() && encryptedResponseL1.getNonce() != null ? Base64.getDecoder().decode(encryptedResponseL1.getNonce()) : null; String applicationKey = context.getModel().getApplicationKey(); final byte[] associatedDataL1 = context.getModel().getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), applicationKey, null) : null; - Long timestampL1 = encryptedResponseL1.getTimestamp(); + Long timestampL1 = version.useTimestamp() ? encryptedResponseL1.getTimestamp() : null; EciesCryptogram responseCryptogramL1 = new EciesCryptogram(ephemeralPublicKeyL1, macL1, encryptedDataL1); EciesParameters eciesParametersL1 = new EciesParameters(nonceL1, associatedDataL1, timestampL1); @@ -171,12 +172,12 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon ); // Decrypt layer 2 response - byte[] ephemeralPublicKeyL2 = Base64.getDecoder().decode(responseL1.getActivationData().getEphemeralPublicKey()); + byte[] ephemeralPublicKeyL2 = securityContext.getEncryptorL2().getEnvelopeKey().getEphemeralKeyPublic(); byte[] macL2 = Base64.getDecoder().decode(responseL1.getActivationData().getMac()); byte[] encryptedDataL2 = Base64.getDecoder().decode(responseL1.getActivationData().getEncryptedData()); - byte[] nonceL2 = responseL1.getActivationData().getNonce() != null ? Base64.getDecoder().decode(responseL1.getActivationData().getNonce()) : null; + byte[] nonceL2 = version.useDifferentIvForResponse() && responseL1.getActivationData().getNonce() != null ? Base64.getDecoder().decode(responseL1.getActivationData().getNonce()) : null; final byte[] associatedDataL2 = context.getModel().getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), applicationKey, null) : null; - Long timestampL2 = responseL1.getActivationData().getTimestamp(); + Long timestampL2 = version.useTimestamp() ? responseL1.getActivationData().getTimestamp() : null; EciesCryptogram responseCryptogramL2 = new EciesCryptogram(ephemeralPublicKeyL2, macL2, encryptedDataL2); EciesParameters eciesParametersL2 = new EciesParameters(nonceL2, associatedDataL2, timestampL2); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java index c97a6fd5..0d3671bb 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java @@ -224,16 +224,18 @@ public void addEncryptedRequest(StepContext stepContext, String applicatio */ public T decryptResponse(StepContext stepContext, Class cls, EciesScope eciesScope, byte[] associatedData) throws Exception { try { - SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); + final PowerAuthVersion version = stepContext.getModel().getVersion(); + final SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); EciesEncryptedResponse encryptedResponse = stepContext.getResponseContext().getResponseBodyObject(); final byte[] transportMasterKeyBytes = Base64.getDecoder().decode(stepContext.getModel().getResultStatus().getTransportMasterKey()); - final byte[] nonceBytes = encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : null; + final byte[] nonceBytes = version.useDifferentIvForResponse() && encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : null; + final Long timestamp = version.useTimestamp() ? encryptedResponse.getTimestamp() : null; EciesParameters eciesParameters = EciesParameters.builder() .nonce(nonceBytes) - .timestamp(encryptedResponse.getTimestamp()) + .timestamp(timestamp) .build(); String applicationSecret = (String) stepContext.getModel().toMap().get("APPLICATION_SECRET"); - byte[] ephemeralPublicKey = Base64.getDecoder().decode(encryptedResponse.getEphemeralPublicKey()); + byte[] ephemeralPublicKey = securityContext.getEncryptor().getEnvelopeKey().getEphemeralKeyPublic(); EciesEncryptor encryptor = securityContext.getEncryptor(); EciesDecryptor eciesDecryptor; if (eciesScope == EciesScope.ACTIVATION_SCOPE) { diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java index 8b78574c..b0039a6d 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java @@ -86,34 +86,6 @@ public static EciesEncryptor createEncryptor(String applicationSecretValue, transportMasterKeyBytes, sharedInfo, parameters); } - /** - * Creates new decryptor - * - * @param applicationSecretValue Application secret value - * @param resultStatusObject Activation status object - * @param envelopeKey Envelope key - * @param ephemeralPublicKey Ephemeral public key - * - * @return New decryptor instance - * @throws CryptoProviderException when an error during encryptor preparation occurred - * @throws GenericCryptoException when an error during encryptor preparation occurred - */ - public static EciesDecryptor createDecryptor(String applicationSecretValue, - ResultStatusObject resultStatusObject, - EciesEnvelopeKey envelopeKey, - byte[] ephemeralPublicKey, - PowerAuthVersion version, - byte[] associatedData) - throws CryptoProviderException, GenericCryptoException { - final byte[] applicationSecret = applicationSecretValue.getBytes(StandardCharsets.UTF_8); - final byte[] transportMasterKeyBytes = Base64.getDecoder().decode(resultStatusObject.getTransportMasterKey()); - final Long timestamp = version.useTimestamp() ? new Date().getTime() : null; - final byte[] nonceBytes = version.useIv() ? new KeyGenerator().generateRandomBytes(16) : null; - final EciesParameters parameters = EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); - return ECIES_FACTORY.getEciesDecryptor(EciesScope.ACTIVATION_SCOPE, envelopeKey, applicationSecret, - transportMasterKeyBytes, parameters, ephemeralPublicKey); - } - /** * Encrypts an object using the provided encryptor *

    The object will be serialized to json and the json bytes will be then encrypted

    From 10734c2548350ca427c1911436ed1b1fe5b95a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Wed, 2 Aug 2023 09:09:24 +0200 Subject: [PATCH 33/53] Fixed compilation problems after PR #321 (related to #320) --- .../powerauth/lib/cmd/steps/AbstractBaseStep.java | 1 + .../security/powerauth/lib/cmd/util/EncryptionUtil.java | 9 ++++++--- .../security/powerauth/lib/cmd/util/SecurityUtil.java | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java index 0d3671bb..13b635b3 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java @@ -218,6 +218,7 @@ public void addEncryptedRequest(StepContext stepContext, String applicatio * @param stepContext Step context * @param cls Class type of the decrypted object * @param Class of the decrypted object + * @param eciesScope Scope of ECIES * @param associatedData Data associated with ECIES * @return Decrypted object from the provided response * @throws Exception when an error during object decryption occurred diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java index 0f19dbbe..72f79330 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java @@ -45,17 +45,20 @@ public class EncryptionUtil { * Process an encrypted response for a step. * @param stepContext Step context. * @param stepId Step identifier. + * @param eciesScope Scope of ECIES. + * @param applicationSecret Application's secret. + * @param associatedData Associated data for ECIES. * @throws Exception Thrown in case response decryption fails. */ public static void processEncryptedResponse(StepContext stepContext, String stepId, String applicationSecret, EciesScope eciesScope, byte[] associatedData) throws Exception { ResponseContext responseContext = stepContext.getResponseContext(); EciesEncryptor encryptor = ((SimpleSecurityContext) stepContext.getSecurityContext()).getEncryptor(); + final PowerAuthVersion version = stepContext.getModel().getVersion(); final String nonce = responseContext.getResponseBodyObject().getNonce(); - final byte[] nonceBytes = nonce != null ? Base64.getDecoder().decode(nonce) : null; + final byte[] nonceBytes = version.useDifferentIvForResponse() && nonce != null ? Base64.getDecoder().decode(nonce) : null; final Long timestamp = responseContext.getResponseBodyObject().getTimestamp(); - final String ephemeralPublicKey = responseContext.getResponseBodyObject().getEphemeralPublicKey(); - final byte[] ephemeralPublicKeyBytes = Base64.getDecoder().decode(ephemeralPublicKey); + final byte[] ephemeralPublicKeyBytes = encryptor.getEnvelopeKey().getEphemeralKeyPublic(); final byte[] transportMasterKeyBytes = eciesScope == EciesScope.ACTIVATION_SCOPE ? Base64.getDecoder().decode(stepContext.getModel().getResultStatus().getTransportMasterKey()) : null; EciesParameters eciesParameters = EciesParameters.builder().nonce(nonceBytes).timestamp(timestamp).associatedData(associatedData).build(); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java index b0039a6d..52903721 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java @@ -62,6 +62,8 @@ public class SecurityUtil { * @param applicationSecretValue Application secret value * @param resultStatusObject Activation status object * @param sharedInfo Shared info parameter value + * @param associatedData Associated data for ECIES. + * @param version Protocol version. * * @return New encryptor instance * @throws CryptoProviderException when an error during encryptor preparation occurred @@ -111,13 +113,14 @@ public static EciesPayload encryptObject(EciesEncryptor encryptor, Object value, * * @param decryptor Decryptor * @param encryptedResponse Encrypted response + * @param associatedData Associated data for ECIES * @return decrypted bytes * @throws EciesException when an error during decryption occurred */ public static byte[] decryptBytesFromResponse(EciesDecryptor decryptor, EciesEncryptedResponse encryptedResponse, byte[] associatedData) throws EciesException { - final byte[] ephemeralPublicKey = Base64.getDecoder().decode(encryptedResponse.getEphemeralPublicKey()); + final byte[] ephemeralPublicKey = decryptor.getEnvelopeKey().getEphemeralKeyPublic(); final byte[] mac = Base64.getDecoder().decode(encryptedResponse.getMac()); final byte[] encryptedData = Base64.getDecoder().decode(encryptedResponse.getEncryptedData()); final byte[] nonce = encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : null; From 3e4856c31f6f8f2f8ee145f96e07c230893d2c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Thu, 3 Aug 2023 15:36:46 +0200 Subject: [PATCH 34/53] Fix #323: Fixed ECIES for protocol 3.1 and 3.0 --- .../lib/cmd/steps/AbstractActivationStep.java | 37 +++---- .../lib/cmd/steps/AbstractBaseStep.java | 30 +++++- .../security/ActivationSecurityContext.java | 11 +++ .../security/SimpleSecurityContext.java | 6 ++ .../cmd/steps/v3/ConfirmRecoveryCodeStep.java | 2 - .../lib/cmd/steps/v3/CreateTokenStep.java | 3 - .../lib/cmd/steps/v3/EncryptStep.java | 24 ++--- .../lib/cmd/steps/v3/SignAndEncryptStep.java | 9 +- .../lib/cmd/steps/v3/StartUpgradeStep.java | 2 - .../lib/cmd/steps/v3/TokenAndEncryptStep.java | 9 +- .../lib/cmd/steps/v3/VaultUnlockStep.java | 2 - .../lib/cmd/util/EncryptionUtil.java | 91 ----------------- .../powerauth/lib/cmd/util/SecurityUtil.java | 97 +++++++++++++------ 13 files changed, 149 insertions(+), 174 deletions(-) delete mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/EncryptionUtil.java diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java index c704d606..566a535f 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java @@ -38,7 +38,6 @@ import io.getlime.security.powerauth.lib.cmd.steps.model.data.ActivationData; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; import io.getlime.security.powerauth.lib.cmd.util.EncryptedStorageUtil; -import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; import io.getlime.security.powerauth.lib.cmd.util.SecurityUtil; import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; @@ -143,20 +142,22 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon byte[] ephemeralPublicKeyL1 = securityContext.getEncryptorL1().getEnvelopeKey().getEphemeralKeyPublic(); byte[] macL1 = Base64.getDecoder().decode(encryptedResponseL1.getMac()); byte[] encryptedDataL1 = Base64.getDecoder().decode(encryptedResponseL1.getEncryptedData()); - byte[] nonceL1 = version.useDifferentIvForResponse() && encryptedResponseL1.getNonce() != null ? Base64.getDecoder().decode(encryptedResponseL1.getNonce()) : null; + byte[] nonceL1 = version.useDifferentIvForResponse() && encryptedResponseL1.getNonce() != null + ? Base64.getDecoder().decode(encryptedResponseL1.getNonce()) + : securityContext.getRequestParametersL1().getNonce(); String applicationKey = context.getModel().getApplicationKey(); - final byte[] associatedDataL1 = context.getModel().getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), applicationKey, null) : null; + final byte[] associatedData = securityContext.getRequestParametersL1().getAssociatedData(); Long timestampL1 = version.useTimestamp() ? encryptedResponseL1.getTimestamp() : null; EciesCryptogram responseCryptogramL1 = new EciesCryptogram(ephemeralPublicKeyL1, macL1, encryptedDataL1); - EciesParameters eciesParametersL1 = new EciesParameters(nonceL1, associatedDataL1, timestampL1); + EciesParameters eciesParametersL1 = new EciesParameters(nonceL1, associatedData, timestampL1); EciesPayload eciesPayloadL1 = new EciesPayload(responseCryptogramL1, eciesParametersL1); String applicationSecret = context.getModel().getApplicationSecret(); EciesEncryptor encryptor = securityContext.getEncryptorL1(); EciesDecryptor eciesDecryptorL1 = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, - eciesParametersL1, responseCryptogramL1.getEphemeralPublicKey()); + eciesParametersL1, ephemeralPublicKeyL1); byte[] decryptedDataL1 = eciesDecryptorL1.decrypt(eciesPayloadL1); @@ -175,17 +176,18 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon byte[] ephemeralPublicKeyL2 = securityContext.getEncryptorL2().getEnvelopeKey().getEphemeralKeyPublic(); byte[] macL2 = Base64.getDecoder().decode(responseL1.getActivationData().getMac()); byte[] encryptedDataL2 = Base64.getDecoder().decode(responseL1.getActivationData().getEncryptedData()); - byte[] nonceL2 = version.useDifferentIvForResponse() && responseL1.getActivationData().getNonce() != null ? Base64.getDecoder().decode(responseL1.getActivationData().getNonce()) : null; - final byte[] associatedDataL2 = context.getModel().getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), applicationKey, null) : null; + byte[] nonceL2 = version.useDifferentIvForResponse() && responseL1.getActivationData().getNonce() != null + ? Base64.getDecoder().decode(responseL1.getActivationData().getNonce()) + : securityContext.getRequestParametersL2().getNonce(); Long timestampL2 = version.useTimestamp() ? responseL1.getActivationData().getTimestamp() : null; EciesCryptogram responseCryptogramL2 = new EciesCryptogram(ephemeralPublicKeyL2, macL2, encryptedDataL2); - EciesParameters eciesParametersL2 = new EciesParameters(nonceL2, associatedDataL2, timestampL2); + EciesParameters eciesParametersL2 = new EciesParameters(nonceL2, associatedData, timestampL2); EciesPayload responsePayloadL2 = new EciesPayload(responseCryptogramL2, eciesParametersL2); EciesEncryptor encryptorL2 = securityContext.getEncryptorL2(); EciesDecryptor eciesDecryptorL2 = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, encryptorL2.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, - eciesParametersL2, responseCryptogramL2.getEphemeralPublicKey()); + eciesParametersL2, ephemeralPublicKeyL2); byte[] decryptedDataL2 = eciesDecryptorL2.decrypt(responsePayloadL2); // Convert activation layer 2 response from JSON to object and extract activation parameters @@ -280,9 +282,9 @@ protected void addEncryptedRequest(StepContext stepCo final byte[] applicationSecret = model.getApplicationSecret().getBytes(StandardCharsets.UTF_8); final Long timestamp = version.useTimestamp() ? new Date().getTime() : null; - final byte[] associatedData = version.useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, version.toString(), new String(applicationKey, StandardCharsets.UTF_8), null) : null; - final byte[] nonceBytesL1 = version.useIv() ? new KeyGenerator().generateRandomBytes(16) : null; - final byte[] nonceBytesL2 = version.useIv() ? new KeyGenerator().generateRandomBytes(16) : null; + final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, version.toString(), new String(applicationKey, StandardCharsets.UTF_8), null); + final byte[] nonceBytesL1 = version.useIv() ? KEY_GENERATOR.generateRandomBytes(16) : null; + final byte[] nonceBytesL2 = version.useIv() ? KEY_GENERATOR.generateRandomBytes(16) : null; final EciesParameters eciesParametersL1 = EciesParameters.builder().nonce(nonceBytesL1).associatedData(associatedData).timestamp(timestamp).build(); final EciesParameters eciesParametersL2 = EciesParameters.builder().nonce(nonceBytesL2).associatedData(associatedData).timestamp(timestamp).build(); @@ -294,6 +296,8 @@ protected void addEncryptedRequest(StepContext stepCo ActivationSecurityContext securityContext = ActivationSecurityContext.builder() .encryptorL1(eciesEncryptorL1) .encryptorL2(eciesEncryptorL2) + .requestParametersL1(eciesParametersL1) + .requestParametersL2(eciesParametersL2) .deviceKeyPair(deviceKeyPair) .build(); stepContext.setSecurityContext(securityContext); @@ -339,11 +343,10 @@ protected void addEncryptedRequest(StepContext stepCo final boolean useTimestamp = model.getVersion().useTimestamp(); // Encrypt request data using ECIES in application scope with sharedInfo1 = /pa/activation - final byte[] associatedDataL2 = useTimestamp ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, version.toString(), new String(applicationKey, StandardCharsets.UTF_8), null) : null; - EciesPayload eciesPayloadL2 = SecurityUtil.encryptObject(securityContext.getEncryptorL2(), requestL2, useIv, useTimestamp, associatedDataL2); + EciesPayload eciesPayloadL2 = SecurityUtil.encryptObject(eciesEncryptorL2, requestL2, eciesParametersL2); // Prepare the encrypted layer 2 request - EciesEncryptedRequest encryptedRequestL2 = SecurityUtil.createEncryptedRequest(eciesPayloadL2, useIv, useTimestamp); + EciesEncryptedRequest encryptedRequestL2 = SecurityUtil.createEncryptedRequest(eciesPayloadL2); // Prepare activation layer 1 request which is decryptable on intermediate server ActivationLayer1Request requestL1 = prepareLayer1Request(stepContext, encryptedRequestL2); @@ -357,10 +360,10 @@ protected void addEncryptedRequest(StepContext stepCo ); // Encrypt the layer 1 request using ECIES in application scope with sharedInfo1 = /pa/generic/application - EciesPayload eciesPayloadL1 = SecurityUtil.encryptObject(securityContext.getEncryptorL1(), requestL1, useIv, useTimestamp, associatedData); + EciesPayload eciesPayloadL1 = SecurityUtil.encryptObject(eciesEncryptorL1, requestL1, eciesParametersL1); // Prepare the encrypted layer 1 request - EciesEncryptedRequest encryptedRequestL1 = SecurityUtil.createEncryptedRequest(eciesPayloadL1, useIv, useTimestamp); + EciesEncryptedRequest encryptedRequestL1 = SecurityUtil.createEncryptedRequest(eciesPayloadL1); stepContext.getRequestContext().setRequestObject(encryptedRequestL1); } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java index 13b635b3..b5477522 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java @@ -10,6 +10,8 @@ import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; +import io.getlime.security.powerauth.crypto.lib.model.exception.CryptoProviderException; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.DisabledStepLogger; @@ -75,6 +77,7 @@ public abstract class AbstractBaseStep implements Bas protected final StepLoggerFactory stepLoggerFactory; private static final EciesFactory ECIES_FACTORY = new EciesFactory(); + private static final KeyGenerator KEY_GENERATOR = new KeyGenerator(); /** * Constructor @@ -192,22 +195,26 @@ public void addEncryptedRequest(StepContext stepContext, String applicatio ResultStatusObject resultStatusObject = model.getResultStatus(); EciesEncryptor encryptor; + EciesParameters parameters; if (securityContext == null) { - encryptor = SecurityUtil.createEncryptor(applicationSecret, resultStatusObject, eciesSharedInfo, stepContext.getModel().getVersion(), associatedData); + parameters = getRequestEciesParameters(stepContext.getModel().getVersion(), associatedData); + encryptor = SecurityUtil.createEncryptorForActivationScope(applicationSecret, resultStatusObject, eciesSharedInfo, parameters); stepContext.setSecurityContext( SimpleSecurityContext.builder() .encryptor(encryptor) + .requestParameters(parameters) .build() ); } else { encryptor = securityContext.getEncryptor(); + parameters = securityContext.getRequestParameters(); } final boolean useIv = model.getVersion().useIv(); final boolean useTimestamp = model.getVersion().useTimestamp(); - final EciesPayload eciesPayload = encryptor.encrypt(data, useIv, true, associatedData); - final EciesEncryptedRequest encryptedRequest = SecurityUtil.createEncryptedRequest(eciesPayload, useIv, useTimestamp); + final EciesPayload eciesPayload = encryptor.encrypt(data, parameters); + final EciesEncryptedRequest encryptedRequest = SecurityUtil.createEncryptedRequest(eciesPayload); stepContext.getRequestContext().setRequestObject(encryptedRequest); } @@ -229,7 +236,7 @@ public T decryptResponse(StepContext stepContext, final SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); EciesEncryptedResponse encryptedResponse = stepContext.getResponseContext().getResponseBodyObject(); final byte[] transportMasterKeyBytes = Base64.getDecoder().decode(stepContext.getModel().getResultStatus().getTransportMasterKey()); - final byte[] nonceBytes = version.useDifferentIvForResponse() && encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : null; + final byte[] nonceBytes = version.useDifferentIvForResponse() && encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : securityContext.getRequestParameters().getNonce(); final Long timestamp = version.useTimestamp() ? encryptedResponse.getTimestamp() : null; EciesParameters eciesParameters = EciesParameters.builder() .nonce(nonceBytes) @@ -249,7 +256,7 @@ public T decryptResponse(StepContext stepContext, eciesParameters, ephemeralPublicKey); } - byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(eciesDecryptor, encryptedResponse, associatedData); + byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(eciesDecryptor, encryptedResponse, eciesParameters); final T responsePayload = RestClientConfiguration.defaultMapper().readValue(decryptedBytes, cls); stepContext.getResponseContext().setResponsePayloadDecrypted(responsePayload); @@ -269,6 +276,19 @@ public T decryptResponse(StepContext stepContext, } } + /** + * Createa EciesParameters object for the new encrypted request. + * @param version Protocol version. + * @param associatedData Associated data to be a part of the request. + * @return EciesParameters object. + * @throws CryptoProviderException In case of random generator fails. + */ + public EciesParameters getRequestEciesParameters(PowerAuthVersion version, byte[] associatedData) throws CryptoProviderException { + final Long timestamp = version.useTimestamp() ? new Date().getTime() : null; + final byte[] nonceBytes = version.useIv() ? KEY_GENERATOR.generateRandomBytes(16) : null; + return EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); + } + /** * Optional processing of the response data * diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java index 25c80ca9..a4172dc7 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java @@ -18,6 +18,8 @@ import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; import lombok.Builder; import lombok.Data; @@ -42,6 +44,15 @@ public class ActivationSecurityContext implements SecurityContext { */ private EciesEncryptor encryptorL2; + /** + * ECIES parameters used for request encryption on layer 1 + */ + private EciesParameters requestParametersL1; + /** + * ECIES parameters used for request encryption on layer 2 + */ + private EciesParameters requestParametersL2; + /** * Device key pair */ diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SimpleSecurityContext.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SimpleSecurityContext.java index 853620ce..ce15afa3 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SimpleSecurityContext.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SimpleSecurityContext.java @@ -17,6 +17,7 @@ package io.getlime.security.powerauth.lib.cmd.steps.context.security; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; import lombok.Builder; import lombok.Data; @@ -34,4 +35,9 @@ public class SimpleSecurityContext implements SecurityContext { */ private EciesEncryptor encryptor; + /** + * ECIES parameters used for request encryption + */ + private EciesParameters requestParameters; + } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java index 6c8f11e5..8a5fe96f 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java @@ -31,8 +31,6 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.ConfirmRecoveryCodeStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.model.StartUpgradeStepModel; -import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; import io.getlime.security.powerauth.rest.api.model.request.ConfirmRecoveryRequestPayload; import io.getlime.security.powerauth.rest.api.model.response.ConfirmRecoveryResponsePayload; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java index 4f6bd63d..1c195b06 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java @@ -32,15 +32,12 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateTokenStepModel; -import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; -import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.rest.api.model.entity.TokenResponsePayload; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; -import java.util.Base64; import java.util.Map; /** diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java index 1aecd29f..580d4780 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java @@ -38,7 +38,6 @@ import io.getlime.security.powerauth.lib.cmd.steps.context.security.SimpleSecurityContext; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; -import io.getlime.security.powerauth.lib.cmd.util.EncryptionUtil; import io.getlime.security.powerauth.lib.cmd.util.SecurityUtil; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.springframework.beans.factory.annotation.Autowired; @@ -122,6 +121,7 @@ public StepContext prepareStepContext( final byte[] applicationSecret = model.getApplicationSecret().getBytes(StandardCharsets.UTF_8); final EciesEncryptor encryptor; + final EciesParameters parameters; // Prepare the encryption header final EciesSharedInfo1 eciesSharedInfo1; @@ -130,9 +130,10 @@ public StepContext prepareStepContext( case "application" -> { // Prepare ECIES encryptor with sharedInfo1 = /pa/generic/application eciesSharedInfo1 = EciesSharedInfo1.APPLICATION_SCOPE_GENERIC; - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), null) : null; + final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), null); + parameters = getRequestEciesParameters(model.getVersion(), associatedData); encryptor = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), - applicationSecret, eciesSharedInfo1, getEciesParameters(model.getVersion(), associatedData)); + applicationSecret, eciesSharedInfo1, parameters); header = new PowerAuthEncryptionHttpHeader(model.getApplicationKey(), model.getVersion().value()); } case "activation" -> { @@ -140,8 +141,9 @@ public StepContext prepareStepContext( eciesSharedInfo1 = EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC; // Prepare ECIES encryptor with sharedInfo1 = /pa/generic/activation final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - encryptor = SecurityUtil.createEncryptor(model.getApplicationSecret(), resultStatusObject, EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, model.getVersion(), associatedData); + final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId); + parameters = getRequestEciesParameters(model.getVersion(), associatedData); + encryptor = SecurityUtil.createEncryptorForActivationScope(model.getApplicationSecret(), resultStatusObject, EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, parameters); header = new PowerAuthEncryptionHttpHeader(model.getApplicationKey(), activationId, model.getVersion().value()); } default -> { @@ -154,6 +156,7 @@ public StepContext prepareStepContext( stepContext.setSecurityContext( SimpleSecurityContext.builder() .encryptor(encryptor) + .requestParameters(parameters) .build() ); @@ -189,14 +192,7 @@ public void processResponse(StepContext prepareStep // Encrypt the request final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId); addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, requestDataBytes, associatedData); incrementCounter(model); @@ -155,8 +154,8 @@ public void processResponse(StepContext prepareStep // Encrypt the request final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; + final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId); addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, requestDataBytes, associatedData); return stepContext; @@ -153,8 +152,8 @@ public void processResponse(StepContext stepContext, String stepId, String applicationSecret, EciesScope eciesScope, byte[] associatedData) throws Exception { - ResponseContext responseContext = stepContext.getResponseContext(); - EciesEncryptor encryptor = ((SimpleSecurityContext) stepContext.getSecurityContext()).getEncryptor(); - - final PowerAuthVersion version = stepContext.getModel().getVersion(); - final String nonce = responseContext.getResponseBodyObject().getNonce(); - final byte[] nonceBytes = version.useDifferentIvForResponse() && nonce != null ? Base64.getDecoder().decode(nonce) : null; - final Long timestamp = responseContext.getResponseBodyObject().getTimestamp(); - final byte[] ephemeralPublicKeyBytes = encryptor.getEnvelopeKey().getEphemeralKeyPublic(); - final byte[] transportMasterKeyBytes = eciesScope == EciesScope.ACTIVATION_SCOPE ? Base64.getDecoder().decode(stepContext.getModel().getResultStatus().getTransportMasterKey()) : null; - - EciesParameters eciesParameters = EciesParameters.builder().nonce(nonceBytes).timestamp(timestamp).associatedData(associatedData).build(); - - EciesDecryptor eciesDecryptor; - if (eciesScope == EciesScope.ACTIVATION_SCOPE) { - eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.ACTIVATION_SCOPE, - encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), transportMasterKeyBytes, - eciesParameters, ephemeralPublicKeyBytes); - } else { - eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, - encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, - eciesParameters, ephemeralPublicKeyBytes); - } - - final byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(eciesDecryptor, responseContext.getResponseBodyObject(), associatedData); - - String decryptedMessage = new String(decryptedBytes, StandardCharsets.UTF_8); - stepContext.getModel().getResultStatus().setResponseData(decryptedMessage); - - stepContext.getStepLogger().writeItem( - stepId + "-response-decrypt", - "Decrypted Response", - "Following data were decrypted", - "OK", - decryptedMessage - ); - } - -} \ No newline at end of file diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java index 52903721..70fb1606 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java @@ -18,15 +18,16 @@ import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEnvelopeKey; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.exception.EciesException; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.*; -import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; import io.getlime.security.powerauth.crypto.lib.model.exception.CryptoProviderException; import io.getlime.security.powerauth.crypto.lib.model.exception.GenericCryptoException; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.steps.context.ResponseContext; +import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; +import io.getlime.security.powerauth.lib.cmd.steps.context.security.SimpleSecurityContext; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; @@ -37,7 +38,6 @@ import java.security.interfaces.ECPublicKey; import java.security.spec.InvalidKeySpecException; import java.util.Base64; -import java.util.Date; /** * Helper class with security utilities. @@ -62,8 +62,7 @@ public class SecurityUtil { * @param applicationSecretValue Application secret value * @param resultStatusObject Activation status object * @param sharedInfo Shared info parameter value - * @param associatedData Associated data for ECIES. - * @param version Protocol version. + * @param parameters ECIES parameters. * * @return New encryptor instance * @throws CryptoProviderException when an error during encryptor preparation occurred @@ -71,19 +70,15 @@ public class SecurityUtil { * @throws InvalidKeySpecException when an error during server public key processing occurred * @throws EciesException when an encryption error occurs */ - public static EciesEncryptor createEncryptor(String applicationSecretValue, - ResultStatusObject resultStatusObject, - EciesSharedInfo1 sharedInfo, - PowerAuthVersion version, - byte[] associatedData) + public static EciesEncryptor createEncryptorForActivationScope(String applicationSecretValue, + ResultStatusObject resultStatusObject, + EciesSharedInfo1 sharedInfo, + EciesParameters parameters) throws CryptoProviderException, GenericCryptoException, InvalidKeySpecException, EciesException { final byte[] applicationSecret = applicationSecretValue.getBytes(StandardCharsets.UTF_8); final byte[] serverPublicKeyBytes = Base64.getDecoder().decode(resultStatusObject.getServerPublicKey()); final byte[] transportMasterKeyBytes = Base64.getDecoder().decode(resultStatusObject.getTransportMasterKey()); final ECPublicKey serverPublicKey = (ECPublicKey) KEY_CONVERTOR.convertBytesToPublicKey(serverPublicKeyBytes); - final Long timestamp = version.useTimestamp() ? new Date().getTime() : null; - final byte[] nonceBytes = version.useIv() ? new KeyGenerator().generateRandomBytes(16) : null; - final EciesParameters parameters = EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); return ECIES_FACTORY.getEciesEncryptorForActivation(serverPublicKey, applicationSecret, transportMasterKeyBytes, sharedInfo, parameters); } @@ -94,18 +89,16 @@ public static EciesEncryptor createEncryptor(String applicationSecretValue, * * @param encryptor Encyptor instance * @param value Object value to be encrypted - * @param useIv True for encryption with non-zero initialization vector - * @param useTimestamp True when timestamp is used - * @param associatedData Data associated with ECIES request + * @param parameters ECIES parameters. * @return Cryptogram value of the provided object. * @throws EciesException when an error during object encryption occurred * @throws IOException when an error during object encryption occurred */ - public static EciesPayload encryptObject(EciesEncryptor encryptor, Object value, boolean useIv, boolean useTimestamp, byte[] associatedData) + public static EciesPayload encryptObject(EciesEncryptor encryptor, Object value, EciesParameters parameters) throws EciesException, IOException { ByteArrayOutputStream baosL = new ByteArrayOutputStream(); RestClientConfiguration.defaultMapper().writeValue(baosL, value); - return encryptor.encrypt(baosL.toByteArray(), useIv, useTimestamp, associatedData); + return encryptor.encrypt(baosL.toByteArray(), parameters); } /** @@ -113,22 +106,23 @@ public static EciesPayload encryptObject(EciesEncryptor encryptor, Object value, * * @param decryptor Decryptor * @param encryptedResponse Encrypted response - * @param associatedData Associated data for ECIES + * @param requestParameters ECIES parameters used to encrypt the request * @return decrypted bytes * @throws EciesException when an error during decryption occurred */ - public static byte[] decryptBytesFromResponse(EciesDecryptor decryptor, EciesEncryptedResponse encryptedResponse, byte[] associatedData) + public static byte[] decryptBytesFromResponse(EciesDecryptor decryptor, EciesEncryptedResponse encryptedResponse, EciesParameters requestParameters) throws EciesException { final byte[] ephemeralPublicKey = decryptor.getEnvelopeKey().getEphemeralKeyPublic(); final byte[] mac = Base64.getDecoder().decode(encryptedResponse.getMac()); final byte[] encryptedData = Base64.getDecoder().decode(encryptedResponse.getEncryptedData()); - final byte[] nonce = encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : null; + // TODO: we trust server here, to do not provide nonce in protocols 3.1 and older in response. + final byte[] nonce = encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : requestParameters.getNonce(); final Long timestamp = encryptedResponse.getTimestamp(); final EciesCryptogram eciesCryptogramResponse = new EciesCryptogram(ephemeralPublicKey, mac, encryptedData); - final EciesParameters parameters = new EciesParameters(nonce, associatedData, timestamp); - final EciesPayload payload = new EciesPayload(eciesCryptogramResponse, parameters); + final EciesParameters responseParameters = new EciesParameters(nonce, requestParameters.getAssociatedData(), timestamp); + final EciesPayload payload = new EciesPayload(eciesCryptogramResponse, responseParameters); return decryptor.decrypt(payload); } @@ -137,18 +131,65 @@ public static byte[] decryptBytesFromResponse(EciesDecryptor decryptor, EciesEnc * Creates an encrypted request instance * * @param eciesPayload Ecies payload data to be sent - * @param useIv True for encryption with non-zero initialization vector - * @param useTimestamp True when timestamp is present * @return Encrypted request instance */ - public static EciesEncryptedRequest createEncryptedRequest(EciesPayload eciesPayload, boolean useIv, boolean useTimestamp) { + public static EciesEncryptedRequest createEncryptedRequest(EciesPayload eciesPayload) { EciesEncryptedRequest request = new EciesEncryptedRequest(); + final byte[] nonce = eciesPayload.getParameters().getNonce(); + final Long timestamp = eciesPayload.getParameters().getTimestamp(); request.setEncryptedData(Base64.getEncoder().encodeToString(eciesPayload.getCryptogram().getEncryptedData())); request.setEphemeralPublicKey(Base64.getEncoder().encodeToString(eciesPayload.getCryptogram().getEphemeralPublicKey())); request.setMac(Base64.getEncoder().encodeToString(eciesPayload.getCryptogram().getMac())); - request.setNonce(useIv ? Base64.getEncoder().encodeToString(eciesPayload.getParameters().getNonce()) : null); - request.setTimestamp(useTimestamp ? new Date().getTime() : null); + request.setNonce(nonce != null ? Base64.getEncoder().encodeToString(nonce) : null); + request.setTimestamp(timestamp); return request; } + /** + * Process an encrypted response for a step. + * @param stepContext Step context. + * @param stepId Step identifier. + * @param eciesScope Scope of ECIES. + * @param applicationSecret Application's secret. + * @param associatedData Associated data for ECIES. + * @throws Exception Thrown in case response decryption fails. + */ + public static void processEncryptedResponse(StepContext stepContext, String stepId, String applicationSecret, EciesScope eciesScope, byte[] associatedData) throws Exception { + ResponseContext responseContext = stepContext.getResponseContext(); + SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); + EciesEncryptor encryptor = securityContext.getEncryptor(); + + final PowerAuthVersion version = stepContext.getModel().getVersion(); + final String nonce = responseContext.getResponseBodyObject().getNonce(); + final byte[] nonceBytes = version.useDifferentIvForResponse() && nonce != null ? Base64.getDecoder().decode(nonce) : securityContext.getRequestParameters().getNonce(); + final Long timestamp = responseContext.getResponseBodyObject().getTimestamp(); + final byte[] ephemeralPublicKeyBytes = encryptor.getEnvelopeKey().getEphemeralKeyPublic(); + final byte[] transportMasterKeyBytes = eciesScope == EciesScope.ACTIVATION_SCOPE ? Base64.getDecoder().decode(stepContext.getModel().getResultStatus().getTransportMasterKey()) : null; + + EciesParameters eciesParameters = EciesParameters.builder().nonce(nonceBytes).timestamp(timestamp).associatedData(associatedData).build(); + + EciesDecryptor eciesDecryptor; + if (eciesScope == EciesScope.ACTIVATION_SCOPE) { + eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.ACTIVATION_SCOPE, + encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), transportMasterKeyBytes, + eciesParameters, ephemeralPublicKeyBytes); + } else { + eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, + encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, + eciesParameters, ephemeralPublicKeyBytes); + } + + final byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(eciesDecryptor, responseContext.getResponseBodyObject(), eciesParameters); + + String decryptedMessage = new String(decryptedBytes, StandardCharsets.UTF_8); + stepContext.getModel().getResultStatus().setResponseData(decryptedMessage); + + stepContext.getStepLogger().writeItem( + stepId + "-response-decrypt", + "Decrypted Response", + "Following data were decrypted", + "OK", + decryptedMessage + ); + } } From 7a7efa89e34a7d69f807afdd7f028d33e9846154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= <1719814+hvge@users.noreply.github.com> Date: Fri, 4 Aug 2023 15:11:05 +0200 Subject: [PATCH 35/53] Update powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Luboš Račanský --- .../security/powerauth/lib/cmd/steps/AbstractBaseStep.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java index b5477522..fdbc93af 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java @@ -277,7 +277,7 @@ public T decryptResponse(StepContext stepContext, } /** - * Createa EciesParameters object for the new encrypted request. + * Create EciesParameters object for the new encrypted request. * @param version Protocol version. * @param associatedData Associated data to be a part of the request. * @return EciesParameters object. From 946333fb0e03859350202fbe88f909a1eadb500a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= <1719814+hvge@users.noreply.github.com> Date: Thu, 24 Aug 2023 13:17:29 +0200 Subject: [PATCH 36/53] Fix #325: Use general encryptor (#328) * Fix #325: Use general encryptor --------- Co-authored-by: Lubos Racansky --- .../cmd/header/EncryptionHeaderProvider.java | 10 +- .../lib/cmd/steps/AbstractActivationStep.java | 115 +++++--------- .../lib/cmd/steps/AbstractBaseStep.java | 146 +++++++++--------- .../lib/cmd/steps/VerifySignatureStep.java | 1 + .../lib/cmd/steps/VerifyTokenStep.java | 1 + .../security/ActivationSecurityContext.java | 23 +-- .../context/security/SecurityContext.java | 8 +- .../security/SimpleSecurityContext.java | 16 +- .../cmd/steps/v3/ActivationRecoveryStep.java | 3 +- .../lib/cmd/steps/v3/CommitUpgradeStep.java | 1 + .../cmd/steps/v3/ConfirmRecoveryCodeStep.java | 15 +- .../cmd/steps/v3/CreateActivationStep.java | 3 +- .../lib/cmd/steps/v3/CreateTokenStep.java | 15 +- .../lib/cmd/steps/v3/EncryptStep.java | 70 +++------ .../lib/cmd/steps/v3/GetStatusStep.java | 1 + .../cmd/steps/v3/PrepareActivationStep.java | 3 +- .../lib/cmd/steps/v3/RemoveStep.java | 1 + .../lib/cmd/steps/v3/RemoveTokenStep.java | 1 + .../lib/cmd/steps/v3/SignAndEncryptStep.java | 16 +- .../lib/cmd/steps/v3/StartUpgradeStep.java | 13 +- .../lib/cmd/steps/v3/TokenAndEncryptStep.java | 19 +-- .../lib/cmd/steps/v3/VaultUnlockStep.java | 14 +- .../powerauth/lib/cmd/util/SecurityUtil.java | 138 +++-------------- 23 files changed, 230 insertions(+), 403 deletions(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/EncryptionHeaderProvider.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/EncryptionHeaderProvider.java index 8939b71a..ccf2b748 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/EncryptionHeaderProvider.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/EncryptionHeaderProvider.java @@ -16,6 +16,7 @@ */ package io.getlime.security.powerauth.lib.cmd.header; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorScope; import io.getlime.security.powerauth.http.PowerAuthEncryptionHttpHeader; import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; @@ -35,12 +36,15 @@ public class EncryptionHeaderProvider implements PowerAuthHeaderProvider stepContext) { EncryptionHeaderData model = stepContext.getModel(); - RequestContext requestContext = stepContext.getRequestContext(); - - String activationId = model.getResultStatus().getActivationId(); + EncryptorScope encryptorScope = stepContext.getSecurityContext().getEncryptorScope(); + if (encryptorScope == null) { + throw new IllegalStateException("Scope is not determined yet. To fix this, move call to addHeader() after addEncryptedRequest call."); + } + String activationId = encryptorScope == EncryptorScope.ACTIVATION_SCOPE ? model.getResultStatus().getActivationId() : null; PowerAuthEncryptionHttpHeader header = new PowerAuthEncryptionHttpHeader(model.getApplicationKey(), activationId, model.getVersion().value()); String headerValue = header.buildHttpHeader(); + RequestContext requestContext = stepContext.getRequestContext(); requestContext.setAuthorizationHeader(headerValue); requestContext.setAuthorizationHeaderName(PowerAuthEncryptionHttpHeader.HEADER_NAME); requestContext.getHttpHeaders().put(PowerAuthEncryptionHttpHeader.HEADER_NAME, headerValue); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java index 566a535f..47dfe79e 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractActivationStep.java @@ -20,12 +20,14 @@ import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.*; +import io.getlime.security.powerauth.crypto.lib.encryptor.ClientEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.EncryptorFactory; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedRequest; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedResponse; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.v3.ClientEncryptorSecrets; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -51,10 +53,8 @@ import javax.crypto.SecretKey; import java.io.Console; -import java.nio.charset.StandardCharsets; import java.security.KeyPair; import java.security.PublicKey; -import java.security.interfaces.ECPublicKey; import java.util.*; /** @@ -66,7 +66,7 @@ public abstract class AbstractActivationStep extends A private static final PowerAuthClientActivation ACTIVATION = new PowerAuthClientActivation(); - private static final EciesFactory ECIES_FACTORY = new EciesFactory(); + private static final EncryptorFactory ENCRYPTOR_FACTORY = new EncryptorFactory(); private static final KeyConvertor KEY_CONVERTOR = new KeyConvertor(); @@ -138,28 +138,13 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon final PowerAuthVersion version = model.getVersion(); final ActivationSecurityContext securityContext = (ActivationSecurityContext) context.getSecurityContext(); - // Read activation layer 1 response and decrypt it - byte[] ephemeralPublicKeyL1 = securityContext.getEncryptorL1().getEnvelopeKey().getEphemeralKeyPublic(); - byte[] macL1 = Base64.getDecoder().decode(encryptedResponseL1.getMac()); - byte[] encryptedDataL1 = Base64.getDecoder().decode(encryptedResponseL1.getEncryptedData()); - byte[] nonceL1 = version.useDifferentIvForResponse() && encryptedResponseL1.getNonce() != null - ? Base64.getDecoder().decode(encryptedResponseL1.getNonce()) - : securityContext.getRequestParametersL1().getNonce(); - String applicationKey = context.getModel().getApplicationKey(); - final byte[] associatedData = securityContext.getRequestParametersL1().getAssociatedData(); - - Long timestampL1 = version.useTimestamp() ? encryptedResponseL1.getTimestamp() : null; - - EciesCryptogram responseCryptogramL1 = new EciesCryptogram(ephemeralPublicKeyL1, macL1, encryptedDataL1); - EciesParameters eciesParametersL1 = new EciesParameters(nonceL1, associatedData, timestampL1); - EciesPayload eciesPayloadL1 = new EciesPayload(responseCryptogramL1, eciesParametersL1); - String applicationSecret = context.getModel().getApplicationSecret(); - EciesEncryptor encryptor = securityContext.getEncryptorL1(); - EciesDecryptor eciesDecryptorL1 = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, - encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, - eciesParametersL1, ephemeralPublicKeyL1); - - byte[] decryptedDataL1 = eciesDecryptorL1.decrypt(eciesPayloadL1); + // Decrypt activation layer 1 response + final byte[] decryptedDataL1 = securityContext.getEncryptorL1().decryptResponse(new EncryptedResponse( + encryptedResponseL1.getEncryptedData(), + encryptedResponseL1.getMac(), + encryptedResponseL1.getNonce(), + encryptedResponseL1.getTimestamp() + )); // Read activation layer 1 response from data ActivationLayer1Response responseL1 = MAPPER.readValue(decryptedDataL1, ActivationLayer1Response.class); @@ -172,23 +157,15 @@ public ResultStatusObject processResponse(EciesEncryptedResponse encryptedRespon responseL1 ); + // Decrypt layer 2 response - byte[] ephemeralPublicKeyL2 = securityContext.getEncryptorL2().getEnvelopeKey().getEphemeralKeyPublic(); - byte[] macL2 = Base64.getDecoder().decode(responseL1.getActivationData().getMac()); - byte[] encryptedDataL2 = Base64.getDecoder().decode(responseL1.getActivationData().getEncryptedData()); - byte[] nonceL2 = version.useDifferentIvForResponse() && responseL1.getActivationData().getNonce() != null - ? Base64.getDecoder().decode(responseL1.getActivationData().getNonce()) - : securityContext.getRequestParametersL2().getNonce(); - Long timestampL2 = version.useTimestamp() ? responseL1.getActivationData().getTimestamp() : null; - - EciesCryptogram responseCryptogramL2 = new EciesCryptogram(ephemeralPublicKeyL2, macL2, encryptedDataL2); - EciesParameters eciesParametersL2 = new EciesParameters(nonceL2, associatedData, timestampL2); - EciesPayload responsePayloadL2 = new EciesPayload(responseCryptogramL2, eciesParametersL2); - EciesEncryptor encryptorL2 = securityContext.getEncryptorL2(); - EciesDecryptor eciesDecryptorL2 = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, - encryptorL2.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, - eciesParametersL2, ephemeralPublicKeyL2); - byte[] decryptedDataL2 = eciesDecryptorL2.decrypt(responsePayloadL2); + EciesEncryptedResponse encryptedResponseL2 = responseL1.getActivationData(); + byte[] decryptedDataL2 = securityContext.getEncryptorL2().decryptResponse(new EncryptedResponse( + encryptedResponseL2.getEncryptedData(), + encryptedResponseL2.getMac(), + encryptedResponseL2.getNonce(), + encryptedResponseL2.getTimestamp() + )); // Convert activation layer 2 response from JSON to object and extract activation parameters ActivationLayer2Response responseL2 = MAPPER.readValue(decryptedDataL2, ActivationLayer2Response.class); @@ -271,33 +248,28 @@ protected ParameterizedTypeReference getResponseTypeRefe * The encrypted request is then added to the request context of this step. * * @param stepContext Step context - * @param version Protocol version * @throws Exception when an error during encryption of the request data occurred */ - protected void addEncryptedRequest(StepContext stepContext, PowerAuthVersion version) throws Exception { + protected void addEncryptedRequest(StepContext stepContext) throws Exception { M model = stepContext.getModel(); // Get activation key and secret - final byte[] applicationKey = model.getApplicationKey().getBytes(StandardCharsets.UTF_8); - final byte[] applicationSecret = model.getApplicationSecret().getBytes(StandardCharsets.UTF_8); - - final Long timestamp = version.useTimestamp() ? new Date().getTime() : null; - final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, version.toString(), new String(applicationKey, StandardCharsets.UTF_8), null); - final byte[] nonceBytesL1 = version.useIv() ? KEY_GENERATOR.generateRandomBytes(16) : null; - final byte[] nonceBytesL2 = version.useIv() ? KEY_GENERATOR.generateRandomBytes(16) : null; - final EciesParameters eciesParametersL1 = EciesParameters.builder().nonce(nonceBytesL1).associatedData(associatedData).timestamp(timestamp).build(); - final EciesParameters eciesParametersL2 = EciesParameters.builder().nonce(nonceBytesL2).associatedData(associatedData).timestamp(timestamp).build(); - - EciesEncryptor eciesEncryptorL1 = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), applicationSecret, EciesSharedInfo1.APPLICATION_SCOPE_GENERIC, eciesParametersL1); - EciesEncryptor eciesEncryptorL2 = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), applicationSecret, EciesSharedInfo1.ACTIVATION_LAYER_2, eciesParametersL2); + ClientEncryptor clientEncryptorL1 = ENCRYPTOR_FACTORY.getClientEncryptor( + EncryptorId.APPLICATION_SCOPE_GENERIC, + new EncryptorParameters(model.getVersion().value(), model.getApplicationKey(), null), + new ClientEncryptorSecrets(model.getMasterPublicKey(), model.getApplicationSecret()) + ); + ClientEncryptor clientEncryptorL2 = ENCRYPTOR_FACTORY.getClientEncryptor( + EncryptorId.ACTIVATION_LAYER_2, + new EncryptorParameters(model.getVersion().value(), model.getApplicationKey(), null), + new ClientEncryptorSecrets(model.getMasterPublicKey(), model.getApplicationSecret()) + ); KeyPair deviceKeyPair = ACTIVATION.generateDeviceKeyPair(); ActivationSecurityContext securityContext = ActivationSecurityContext.builder() - .encryptorL1(eciesEncryptorL1) - .encryptorL2(eciesEncryptorL2) - .requestParametersL1(eciesParametersL1) - .requestParametersL2(eciesParametersL2) + .encryptorL1(clientEncryptorL1) + .encryptorL2(clientEncryptorL2) .deviceKeyPair(deviceKeyPair) .build(); stepContext.setSecurityContext(securityContext); @@ -339,17 +311,14 @@ protected void addEncryptedRequest(StepContext stepCo requestL2.setPlatform(model.getPlatform()); requestL2.setDeviceInfo(model.getDeviceInfo()); - final boolean useIv = model.getVersion().useIv(); - final boolean useTimestamp = model.getVersion().useTimestamp(); - // Encrypt request data using ECIES in application scope with sharedInfo1 = /pa/activation - EciesPayload eciesPayloadL2 = SecurityUtil.encryptObject(eciesEncryptorL2, requestL2, eciesParametersL2); + EncryptedRequest encryptedRequestL2 = SecurityUtil.encryptObject(clientEncryptorL2, requestL2); // Prepare the encrypted layer 2 request - EciesEncryptedRequest encryptedRequestL2 = SecurityUtil.createEncryptedRequest(eciesPayloadL2); + EciesEncryptedRequest encryptedObjectL2 = SecurityUtil.createEncryptedRequest(encryptedRequestL2); // Prepare activation layer 1 request which is decryptable on intermediate server - ActivationLayer1Request requestL1 = prepareLayer1Request(stepContext, encryptedRequestL2); + ActivationLayer1Request requestL1 = prepareLayer1Request(stepContext, encryptedObjectL2); stepContext.getStepLogger().writeItem( getStep().id() + "-request-encrypt", @@ -360,12 +329,12 @@ protected void addEncryptedRequest(StepContext stepCo ); // Encrypt the layer 1 request using ECIES in application scope with sharedInfo1 = /pa/generic/application - EciesPayload eciesPayloadL1 = SecurityUtil.encryptObject(eciesEncryptorL1, requestL1, eciesParametersL1); + EncryptedRequest encryptedRequestL1 = SecurityUtil.encryptObject(clientEncryptorL1, requestL1); // Prepare the encrypted layer 1 request - EciesEncryptedRequest encryptedRequestL1 = SecurityUtil.createEncryptedRequest(eciesPayloadL1); + EciesEncryptedRequest encryptedRequestObjectL1 = SecurityUtil.createEncryptedRequest(encryptedRequestL1); - stepContext.getRequestContext().setRequestObject(encryptedRequestL1); + stepContext.getRequestContext().setRequestObject(encryptedRequestObjectL1); } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java index fdbc93af..f4a14731 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java @@ -1,17 +1,34 @@ +/* + * PowerAuth Command-line utility + * Copyright 2023 Wultra s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.getlime.security.powerauth.lib.cmd.steps; import com.google.common.collect.ImmutableList; import com.wultra.core.rest.client.base.RestClient; import com.wultra.core.rest.client.base.RestClientException; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.encryptor.ClientEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.EncryptorFactory; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedRequest; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedResponse; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.v3.ClientEncryptorSecrets; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.crypto.lib.model.exception.CryptoProviderException; +import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.DisabledStepLogger; @@ -40,7 +57,6 @@ import org.springframework.http.ResponseEntity; import javax.annotation.Nullable; -import java.nio.charset.StandardCharsets; import java.util.*; /** @@ -76,8 +92,9 @@ public abstract class AbstractBaseStep implements Bas */ protected final StepLoggerFactory stepLoggerFactory; - private static final EciesFactory ECIES_FACTORY = new EciesFactory(); + private static final EncryptorFactory ENCRYPTOR_FACTORY = new EncryptorFactory(); private static final KeyGenerator KEY_GENERATOR = new KeyGenerator(); + private static final KeyConvertor KEY_CONVERTOR = new KeyConvertor(); /** * Constructor @@ -179,44 +196,61 @@ public final JSONObject execute(StepLogger stepLogger, Map conte } /** - * Prepares ECIES encryptor and encrypts request data with sharedInfo1. + * Prepares encryptor and encrypts request data with given encryptor. * The encrypted request is then added to the request context of this step. * * @param stepContext Context of this step + * @param applicationKey Application key. * @param applicationSecret Application secret - * @param eciesSharedInfo Parameter sharedInfo1 + * @param encryptorId Encryptor identifier * @param data Request data for the encryption - * @param associatedData Data associated with ECIES * @throws Exception when an error during encryption of the request data occurred */ - public void addEncryptedRequest(StepContext stepContext, String applicationSecret, EciesSharedInfo1 eciesSharedInfo, byte[] data, byte[] associatedData) throws Exception { + public void addEncryptedRequest(StepContext stepContext, String applicationKey, String applicationSecret, EncryptorId encryptorId, byte[] data) throws Exception { M model = stepContext.getModel(); - SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); - ResultStatusObject resultStatusObject = model.getResultStatus(); + final SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); + final ResultStatusObject resultStatusObject = model.getResultStatus(); - EciesEncryptor encryptor; - EciesParameters parameters; + final ClientEncryptor encryptor; + if (securityContext == null) { + final byte[] transportMasterKeyBytes = Base64.getDecoder().decode(resultStatusObject.getTransportMasterKey()); + final EncryptorParameters encryptorParameters = new EncryptorParameters(model.getVersion().value(), applicationKey, resultStatusObject.getActivationId()); + final ClientEncryptorSecrets encryptorSecrets = new ClientEncryptorSecrets(resultStatusObject.getServerPublicKeyObject(), applicationSecret, transportMasterKeyBytes); + encryptor = ENCRYPTOR_FACTORY.getClientEncryptor(encryptorId, encryptorParameters, encryptorSecrets); + stepContext.setSecurityContext(SimpleSecurityContext.builder() + .encryptor(encryptor) + .build()); + } else { + encryptor = securityContext.getEncryptor(); + } + addEncryptedRequest(stepContext, encryptor, data); + } + + /** + * Encrypts request data with given encryptor. + * The encrypted request is then added to the request context of this step. + * + * @param stepContext Context of this step + * @param encryptor Encryptor to use + * @param data Request data for the encryption + * @throws Exception when an error during encryption of the request data occurred + */ + public void addEncryptedRequest(StepContext stepContext, ClientEncryptor encryptor, byte[] data) throws Exception { + M model = stepContext.getModel(); + SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); if (securityContext == null) { - parameters = getRequestEciesParameters(stepContext.getModel().getVersion(), associatedData); - encryptor = SecurityUtil.createEncryptorForActivationScope(applicationSecret, resultStatusObject, eciesSharedInfo, parameters); stepContext.setSecurityContext( SimpleSecurityContext.builder() .encryptor(encryptor) - .requestParameters(parameters) .build() ); - } else { - encryptor = securityContext.getEncryptor(); - parameters = securityContext.getRequestParameters(); + } else if (securityContext.getEncryptor() != encryptor) { + throw new Exception("Different encryptor is already set to security context"); } - final boolean useIv = model.getVersion().useIv(); - final boolean useTimestamp = model.getVersion().useTimestamp(); - - final EciesPayload eciesPayload = encryptor.encrypt(data, parameters); - final EciesEncryptedRequest encryptedRequest = SecurityUtil.createEncryptedRequest(eciesPayload); - - stepContext.getRequestContext().setRequestObject(encryptedRequest); + final EncryptedRequest encryptedRequest = encryptor.encryptRequest(data); + final EciesEncryptedRequest requestObject = SecurityUtil.createEncryptedRequest(encryptedRequest); + stepContext.getRequestContext().setRequestObject(requestObject); } /** @@ -225,39 +259,18 @@ public void addEncryptedRequest(StepContext stepContext, String applicatio * @param stepContext Step context * @param cls Class type of the decrypted object * @param Class of the decrypted object - * @param eciesScope Scope of ECIES - * @param associatedData Data associated with ECIES * @return Decrypted object from the provided response - * @throws Exception when an error during object decryption occurred */ - public T decryptResponse(StepContext stepContext, Class cls, EciesScope eciesScope, byte[] associatedData) throws Exception { + public T decryptResponse(StepContext stepContext, Class cls) { try { - final PowerAuthVersion version = stepContext.getModel().getVersion(); final SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); - EciesEncryptedResponse encryptedResponse = stepContext.getResponseContext().getResponseBodyObject(); - final byte[] transportMasterKeyBytes = Base64.getDecoder().decode(stepContext.getModel().getResultStatus().getTransportMasterKey()); - final byte[] nonceBytes = version.useDifferentIvForResponse() && encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : securityContext.getRequestParameters().getNonce(); - final Long timestamp = version.useTimestamp() ? encryptedResponse.getTimestamp() : null; - EciesParameters eciesParameters = EciesParameters.builder() - .nonce(nonceBytes) - .timestamp(timestamp) - .build(); - String applicationSecret = (String) stepContext.getModel().toMap().get("APPLICATION_SECRET"); - byte[] ephemeralPublicKey = securityContext.getEncryptor().getEnvelopeKey().getEphemeralKeyPublic(); - EciesEncryptor encryptor = securityContext.getEncryptor(); - EciesDecryptor eciesDecryptor; - if (eciesScope == EciesScope.ACTIVATION_SCOPE) { - eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.ACTIVATION_SCOPE, - encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), transportMasterKeyBytes, - eciesParameters, ephemeralPublicKey); - } else { - eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, - encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, - eciesParameters, ephemeralPublicKey); - } - - byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(eciesDecryptor, encryptedResponse, eciesParameters); - + final EciesEncryptedResponse encryptedResponse = stepContext.getResponseContext().getResponseBodyObject(); + final byte[] decryptedBytes = securityContext.getEncryptor().decryptResponse(new EncryptedResponse( + encryptedResponse.getEncryptedData(), + encryptedResponse.getMac(), + encryptedResponse.getNonce(), + encryptedResponse.getTimestamp() + )); final T responsePayload = RestClientConfiguration.defaultMapper().readValue(decryptedBytes, cls); stepContext.getResponseContext().setResponsePayloadDecrypted(responsePayload); @@ -276,19 +289,6 @@ public T decryptResponse(StepContext stepContext, } } - /** - * Create EciesParameters object for the new encrypted request. - * @param version Protocol version. - * @param associatedData Associated data to be a part of the request. - * @return EciesParameters object. - * @throws CryptoProviderException In case of random generator fails. - */ - public EciesParameters getRequestEciesParameters(PowerAuthVersion version, byte[] associatedData) throws CryptoProviderException { - final Long timestamp = version.useTimestamp() ? new Date().getTime() : null; - final byte[] nonceBytes = version.useIv() ? KEY_GENERATOR.generateRandomBytes(16) : null; - return EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); - } - /** * Optional processing of the response data * diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java index 4c71d3a0..d05b0a36 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java @@ -44,6 +44,7 @@ *
  • 2.1
  • *
  • 3.0
  • *
  • 3.1
  • + *
  • 3.2
  • * * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java index be0d7be2..08108370 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java @@ -43,6 +43,7 @@ *
  • 2.1
  • *
  • 3.0
  • *
  • 3.1
  • + *
  • 3.2
  • * * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java index a4172dc7..fc50d575 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/ActivationSecurityContext.java @@ -16,10 +16,8 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.context.security; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; +import io.getlime.security.powerauth.crypto.lib.encryptor.ClientEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorScope; import lombok.Builder; import lombok.Data; @@ -37,25 +35,20 @@ public class ActivationSecurityContext implements SecurityContext { /** * Encryptor used on layer 1 */ - private EciesEncryptor encryptorL1; + private ClientEncryptor encryptorL1; /** * Encryptor used on layer 2 */ - private EciesEncryptor encryptorL2; - - /** - * ECIES parameters used for request encryption on layer 1 - */ - private EciesParameters requestParametersL1; - /** - * ECIES parameters used for request encryption on layer 2 - */ - private EciesParameters requestParametersL2; + private ClientEncryptor encryptorL2; /** * Device key pair */ private KeyPair deviceKeyPair; + @Override + public EncryptorScope getEncryptorScope() { + return EncryptorScope.APPLICATION_SCOPE; + } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SecurityContext.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SecurityContext.java index cf8c9561..d6faa984 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SecurityContext.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SecurityContext.java @@ -16,11 +16,17 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.context.security; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorScope; + /** * Security context interface * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com */ public interface SecurityContext { - + /** + * Implementation must return scope of encryption to be used or null if scope is not determined yet. + * @return {@link EncryptorScope} or null if not known yet. + */ + EncryptorScope getEncryptorScope(); } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SimpleSecurityContext.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SimpleSecurityContext.java index ce15afa3..8995e075 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SimpleSecurityContext.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/context/security/SimpleSecurityContext.java @@ -16,8 +16,8 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.context.security; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.ClientEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorScope; import lombok.Builder; import lombok.Data; @@ -29,15 +29,13 @@ @Data @Builder public class SimpleSecurityContext implements SecurityContext { - /** * Encryptor */ - private EciesEncryptor encryptor; - - /** - * ECIES parameters used for request encryption - */ - private EciesParameters requestParameters; + private ClientEncryptor encryptor; + @Override + public EncryptorScope getEncryptorScope() { + return encryptor != null ? encryptor.getEncryptorId().scope() : null; + } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java index 68b1c8be..18ba62c9 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ActivationRecoveryStep.java @@ -42,6 +42,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com @@ -90,8 +91,8 @@ public StepContext prepareS StepContext stepContext = buildStepContext(stepLogger, model, requestContext); + addEncryptedRequest(stepContext); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); - addEncryptedRequest(stepContext, model.getVersion()); return stepContext; } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CommitUpgradeStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CommitUpgradeStep.java index 931b89f5..9c3dc90a 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CommitUpgradeStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CommitUpgradeStep.java @@ -42,6 +42,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java index 8a5fe96f..ddd59f24 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/ConfirmRecoveryCodeStep.java @@ -16,9 +16,7 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v3; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; -import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -49,6 +47,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com @@ -111,9 +110,7 @@ public StepContext prepare // Encrypt the request final byte[] requestBytesPayload = RestClientConfiguration.defaultMapper().writeValueAsBytes(confirmRequestPayload); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.CONFIRM_RECOVERY_CODE, requestBytesPayload, associatedData); + addEncryptedRequest(stepContext, model.getApplicationKey(), model.getApplicationSecret(), EncryptorId.CONFIRM_RECOVERY_CODE, requestBytesPayload); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); @@ -124,11 +121,7 @@ public StepContext prepare @Override public void processResponse(StepContext stepContext) throws Exception { - final ConfirmRecoveryCodeStepModel model = stepContext.getModel(); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - final ConfirmRecoveryResponsePayload confirmResponsePayload = decryptResponse(stepContext, ConfirmRecoveryResponsePayload.class, EciesScope.ACTIVATION_SCOPE, associatedData); - + final ConfirmRecoveryResponsePayload confirmResponsePayload = decryptResponse(stepContext, ConfirmRecoveryResponsePayload.class); Map objectMap = new HashMap<>(); objectMap.put("alreadyConfirmed", confirmResponsePayload.getAlreadyConfirmed()); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java index b244da63..78265862 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateActivationStep.java @@ -42,6 +42,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com @@ -91,8 +92,8 @@ public StepContext prepareSte StepContext stepContext = buildStepContext(stepLogger, model, requestContext); + addEncryptedRequest(stepContext); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); - addEncryptedRequest(stepContext, model.getVersion()); return stepContext; } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java index 1c195b06..64409baa 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/CreateTokenStep.java @@ -17,9 +17,7 @@ package io.getlime.security.powerauth.lib.cmd.steps.v3; import com.google.common.collect.ImmutableMap; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; -import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -47,6 +45,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com @@ -101,9 +100,7 @@ public StepContext prepareStepCont StepContext stepContext = buildStepContext(stepLogger, model, requestContext); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.CREATE_TOKEN, PowerAuthConst.EMPTY_JSON_BYTES, associatedData); + addEncryptedRequest(stepContext, model.getApplicationKey(), model.getApplicationSecret(), EncryptorId.CREATE_TOKEN, PowerAuthConst.EMPTY_JSON_BYTES); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); @@ -114,10 +111,8 @@ public StepContext prepareStepCont @Override public void processResponse(StepContext stepContext) throws Exception { - final CreateTokenStepModel model = stepContext.getModel(); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - final TokenResponsePayload tokenResponsePayload = decryptResponse(stepContext, TokenResponsePayload.class, EciesScope.ACTIVATION_SCOPE, associatedData); + + final TokenResponsePayload tokenResponsePayload = decryptResponse(stepContext, TokenResponsePayload.class); stepContext.getStepLogger().writeItem( getStep().id() + "-token-obtained", diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java index 580d4780..22d81f1b 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/EncryptStep.java @@ -16,14 +16,12 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v3; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; +import io.getlime.security.powerauth.crypto.lib.encryptor.ClientEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.EncryptorFactory; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.v3.ClientEncryptorSecrets; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.crypto.lib.model.exception.CryptoProviderException; -import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.http.PowerAuthEncryptionHttpHeader; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; @@ -35,18 +33,15 @@ import io.getlime.security.powerauth.lib.cmd.steps.AbstractBaseStep; import io.getlime.security.powerauth.lib.cmd.steps.context.RequestContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; -import io.getlime.security.powerauth.lib.cmd.steps.context.security.SimpleSecurityContext; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; import io.getlime.security.powerauth.lib.cmd.util.SecurityUtil; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import org.bouncycastle.util.encoders.Base64; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.stereotype.Component; -import java.nio.charset.StandardCharsets; -import java.security.interfaces.ECPublicKey; -import java.util.Date; import java.util.Map; /** @@ -56,6 +51,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com @@ -64,7 +60,7 @@ @Component(value = "encryptStepV3") public class EncryptStep extends AbstractBaseStep { - private static final EciesFactory ECIES_FACTORY = new EciesFactory(); + private static final EncryptorFactory ENCRYPTOR_FACTORY = new EncryptorFactory(); private static final KeyGenerator KEY_GENERATOR = new KeyGenerator(); /** @@ -119,31 +115,30 @@ public StepContext prepareStepContext( requestDataBytes ); - final byte[] applicationSecret = model.getApplicationSecret().getBytes(StandardCharsets.UTF_8); - final EciesEncryptor encryptor; - final EciesParameters parameters; + final ClientEncryptor encryptor; // Prepare the encryption header - final EciesSharedInfo1 eciesSharedInfo1; + final EncryptorId encryptorId; final PowerAuthEncryptionHttpHeader header; switch (model.getScope()) { case "application" -> { // Prepare ECIES encryptor with sharedInfo1 = /pa/generic/application - eciesSharedInfo1 = EciesSharedInfo1.APPLICATION_SCOPE_GENERIC; - final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), null); - parameters = getRequestEciesParameters(model.getVersion(), associatedData); - encryptor = ECIES_FACTORY.getEciesEncryptorForApplication((ECPublicKey) model.getMasterPublicKey(), - applicationSecret, eciesSharedInfo1, parameters); + encryptorId = EncryptorId.APPLICATION_SCOPE_GENERIC; + final EncryptorParameters encryptorParameters = new EncryptorParameters(model.getVersion().value(), model.getApplicationKey(), null); + final ClientEncryptorSecrets encryptorSecrets = new ClientEncryptorSecrets(model.getMasterPublicKey(), model.getApplicationSecret()); + encryptor = ENCRYPTOR_FACTORY.getClientEncryptor(encryptorId, encryptorParameters, encryptorSecrets); header = new PowerAuthEncryptionHttpHeader(model.getApplicationKey(), model.getVersion().value()); } case "activation" -> { ResultStatusObject resultStatusObject = model.getResultStatus(); - eciesSharedInfo1 = EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC; + encryptorId = EncryptorId.ACTIVATION_SCOPE_GENERIC; + encryptor = ENCRYPTOR_FACTORY.getClientEncryptor( + encryptorId, + new EncryptorParameters(model.getVersion().value(), model.getApplicationKey(), resultStatusObject.getActivationId()), + new ClientEncryptorSecrets(resultStatusObject.getServerPublicKeyObject(), model.getApplicationSecret(), Base64.decode(resultStatusObject.getTransportMasterKey())) + ); // Prepare ECIES encryptor with sharedInfo1 = /pa/generic/activation final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId); - parameters = getRequestEciesParameters(model.getVersion(), associatedData); - encryptor = SecurityUtil.createEncryptorForActivationScope(model.getApplicationSecret(), resultStatusObject, EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, parameters); header = new PowerAuthEncryptionHttpHeader(model.getApplicationKey(), activationId, model.getVersion().value()); } default -> { @@ -153,16 +148,7 @@ public StepContext prepareStepContext( } } - stepContext.setSecurityContext( - SimpleSecurityContext.builder() - .encryptor(encryptor) - .requestParameters(parameters) - .build() - ); - - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - addEncryptedRequest(stepContext, model.getApplicationSecret(), eciesSharedInfo1, requestDataBytes, associatedData); + addEncryptedRequest(stepContext, encryptor, requestDataBytes); String headerValue = header.buildHttpHeader(); requestContext.setAuthorizationHeader(headerValue); @@ -181,18 +167,6 @@ public StepContext prepareStepContext( @Override public void processResponse(StepContext stepContext) throws Exception { - final EncryptStepModel model = stepContext.getModel(); - final String applicationSecret = model.getApplicationSecret(); - final String activationId; - final EciesScope eciesScope; - if ("activation".equals(model.getScope())) { - eciesScope = EciesScope.ACTIVATION_SCOPE; - activationId = model.getResultStatus().getActivationId(); - } else { - eciesScope = EciesScope.APPLICATION_SCOPE; - activationId = null; - } - final byte[] associatedData = EciesUtils.deriveAssociatedData(eciesScope, model.getVersion().toString(), model.getApplicationKey(), activationId); - SecurityUtil.processEncryptedResponse(stepContext, getStep().id(), applicationSecret, eciesScope, associatedData); + SecurityUtil.processEncryptedResponse(stepContext, getStep().id()); } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java index 2c4fecff..cecfdb51 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/GetStatusStep.java @@ -49,6 +49,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java index 76ea2eae..0c87c1fa 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/PrepareActivationStep.java @@ -46,6 +46,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com @@ -115,8 +116,8 @@ public StepContext prepareSt StepContext stepContext = buildStepContext(stepLogger, model, requestContext); + addEncryptedRequest(stepContext); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); - addEncryptedRequest(stepContext, model.getVersion()); return stepContext; } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveStep.java index c3c3eb79..8d7433d0 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveStep.java @@ -42,6 +42,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java index 2badbc1b..76556e9f 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/RemoveTokenStep.java @@ -45,6 +45,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java index 7524fed4..d371b475 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/SignAndEncryptStep.java @@ -16,9 +16,7 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v3; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; -import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -48,6 +46,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com @@ -140,9 +139,8 @@ public StepContext prepareStep powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); // Encrypt the request - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId); - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, requestDataBytes, associatedData); + + addEncryptedRequest(stepContext, model.getApplicationKey(), model.getApplicationSecret(), EncryptorId.ACTIVATION_SCOPE_GENERIC, requestDataBytes); incrementCounter(model); @@ -151,11 +149,7 @@ public StepContext prepareStep @Override public void processResponse(StepContext stepContext) throws Exception { - final VerifySignatureStepModel model = stepContext.getModel(); - final String applicationSecret = model.getApplicationSecret(); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId); - SecurityUtil.processEncryptedResponse(stepContext, getStep().id(), applicationSecret, EciesScope.ACTIVATION_SCOPE, associatedData); + SecurityUtil.processEncryptedResponse(stepContext, getStep().id()); } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java index 768dba70..43840f1e 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/StartUpgradeStep.java @@ -16,9 +16,7 @@ package io.getlime.security.powerauth.lib.cmd.steps.v3; import com.google.common.collect.ImmutableMap; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; -import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -46,6 +44,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com @@ -99,9 +98,7 @@ public StepContext prepareStepCon StepContext stepContext = buildStepContext(stepLogger, model, requestContext); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.UPGRADE, PowerAuthConst.EMPTY_JSON_BYTES, associatedData); + addEncryptedRequest(stepContext, model.getApplicationKey(), model.getApplicationSecret(), EncryptorId.UPGRADE, PowerAuthConst.EMPTY_JSON_BYTES); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); @@ -111,9 +108,7 @@ public StepContext prepareStepCon @Override public void processResponse(StepContext stepContext) throws Exception { final StartUpgradeStepModel model = stepContext.getModel(); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - final UpgradeResponsePayload responsePayload = decryptResponse(stepContext, UpgradeResponsePayload.class, EciesScope.ACTIVATION_SCOPE, associatedData); + final UpgradeResponsePayload responsePayload = decryptResponse(stepContext, UpgradeResponsePayload.class); // Store the activation status (updated counter) model.getResultStatus().setCtrData(responsePayload.getCtrData()); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java index 767db765..0873eda8 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/TokenAndEncryptStep.java @@ -16,9 +16,7 @@ */ package io.getlime.security.powerauth.lib.cmd.steps.v3; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; -import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthStep; @@ -47,6 +45,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Roman Strobl, roman.strobl@wultra.com @@ -137,23 +136,19 @@ public StepContext prepareStep ); requestContext.setRequestObject(requestDataBytes); - powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); // Encrypt the request - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId); - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.ACTIVATION_SCOPE_GENERIC, requestDataBytes, associatedData); + + addEncryptedRequest(stepContext, model.getApplicationKey(), model.getApplicationSecret(), EncryptorId.ACTIVATION_SCOPE_GENERIC, requestDataBytes); + + powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); return stepContext; } @Override public void processResponse(StepContext stepContext) throws Exception { - final TokenAndEncryptStepModel model = stepContext.getModel(); - final String applicationSecret = model.getApplicationSecret(); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId); - SecurityUtil.processEncryptedResponse(stepContext, getStep().id(), applicationSecret, EciesScope.ACTIVATION_SCOPE, associatedData); + SecurityUtil.processEncryptedResponse(stepContext, getStep().id()); } } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java index a9a32d1e..a02695e8 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/v3/VaultUnlockStep.java @@ -17,9 +17,7 @@ import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.vault.PowerAuthClientVault; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesSharedInfo1; -import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.lib.cmd.consts.BackwardCompatibilityConst; import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthConst; @@ -56,6 +54,7 @@ *
      *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Lukas Lukovsky, lukas.lukovsky@wultra.com @@ -122,9 +121,7 @@ public StepContext prepareStepCont final byte[] requestBytesPayload = RestClientConfiguration.defaultMapper().writeValueAsBytes(requestPayload); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - addEncryptedRequest(stepContext, model.getApplicationSecret(), EciesSharedInfo1.VAULT_UNLOCK, requestBytesPayload, associatedData); + addEncryptedRequest(stepContext, model.getApplicationKey(), model.getApplicationSecret(), EncryptorId.VAULT_UNLOCK, requestBytesPayload); powerAuthHeaderFactory.getHeaderProvider(model).addHeader(stepContext); @@ -135,10 +132,7 @@ public StepContext prepareStepCont @Override public void processResponse(StepContext stepContext) throws Exception { - final VaultUnlockStepModel model = stepContext.getModel(); - final String activationId = model.getResultStatus().getActivationId(); - final byte[] associatedData = model.getVersion().useTimestamp() ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, model.getVersion().toString(), model.getApplicationKey(), activationId) : null; - final VaultUnlockResponsePayload responsePayload = decryptResponse(stepContext, VaultUnlockResponsePayload.class, EciesScope.ACTIVATION_SCOPE, associatedData); + final VaultUnlockResponsePayload responsePayload = decryptResponse(stepContext, VaultUnlockResponsePayload.class); ResultStatusObject resultStatusObject = stepContext.getModel().getResultStatus(); diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java index 70fb1606..63893c69 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/SecurityUtil.java @@ -16,28 +16,19 @@ */ package io.getlime.security.powerauth.lib.cmd.util; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.exception.EciesException; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.*; -import io.getlime.security.powerauth.crypto.lib.model.exception.CryptoProviderException; -import io.getlime.security.powerauth.crypto.lib.model.exception.GenericCryptoException; -import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; -import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.crypto.lib.encryptor.ClientEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.exception.EncryptorException; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedRequest; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedResponse; import io.getlime.security.powerauth.lib.cmd.steps.context.ResponseContext; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.context.security.SimpleSecurityContext; -import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.security.interfaces.ECPublicKey; -import java.security.spec.InvalidKeySpecException; -import java.util.Base64; /** * Helper class with security utilities. @@ -46,102 +37,37 @@ */ public class SecurityUtil { - /** - * ECIES factory - */ - private static final EciesFactory ECIES_FACTORY = new EciesFactory(); - - /** - * Key convertor - */ - private static final KeyConvertor KEY_CONVERTOR = new KeyConvertor(); - - /** - * Creates new encryptor - * - * @param applicationSecretValue Application secret value - * @param resultStatusObject Activation status object - * @param sharedInfo Shared info parameter value - * @param parameters ECIES parameters. - * - * @return New encryptor instance - * @throws CryptoProviderException when an error during encryptor preparation occurred - * @throws GenericCryptoException when an error during encryptor preparation occurred - * @throws InvalidKeySpecException when an error during server public key processing occurred - * @throws EciesException when an encryption error occurs - */ - public static EciesEncryptor createEncryptorForActivationScope(String applicationSecretValue, - ResultStatusObject resultStatusObject, - EciesSharedInfo1 sharedInfo, - EciesParameters parameters) - throws CryptoProviderException, GenericCryptoException, InvalidKeySpecException, EciesException { - final byte[] applicationSecret = applicationSecretValue.getBytes(StandardCharsets.UTF_8); - final byte[] serverPublicKeyBytes = Base64.getDecoder().decode(resultStatusObject.getServerPublicKey()); - final byte[] transportMasterKeyBytes = Base64.getDecoder().decode(resultStatusObject.getTransportMasterKey()); - final ECPublicKey serverPublicKey = (ECPublicKey) KEY_CONVERTOR.convertBytesToPublicKey(serverPublicKeyBytes); - return ECIES_FACTORY.getEciesEncryptorForActivation(serverPublicKey, applicationSecret, - transportMasterKeyBytes, sharedInfo, parameters); - } - /** * Encrypts an object using the provided encryptor *

    The object will be serialized to json and the json bytes will be then encrypted

    * * @param encryptor Encyptor instance * @param value Object value to be encrypted - * @param parameters ECIES parameters. * @return Cryptogram value of the provided object. - * @throws EciesException when an error during object encryption occurred + * @throws EncryptorException when an error during object encryption occurred * @throws IOException when an error during object encryption occurred */ - public static EciesPayload encryptObject(EciesEncryptor encryptor, Object value, EciesParameters parameters) - throws EciesException, IOException { + public static EncryptedRequest encryptObject(ClientEncryptor encryptor, Object value) + throws EncryptorException, IOException { ByteArrayOutputStream baosL = new ByteArrayOutputStream(); RestClientConfiguration.defaultMapper().writeValue(baosL, value); - return encryptor.encrypt(baosL.toByteArray(), parameters); + return encryptor.encryptRequest(baosL.toByteArray()); } - /** - * Decrypts bytes from a response - * - * @param decryptor Decryptor - * @param encryptedResponse Encrypted response - * @param requestParameters ECIES parameters used to encrypt the request - * @return decrypted bytes - * @throws EciesException when an error during decryption occurred - */ - public static byte[] decryptBytesFromResponse(EciesDecryptor decryptor, EciesEncryptedResponse encryptedResponse, EciesParameters requestParameters) - throws EciesException { - - final byte[] ephemeralPublicKey = decryptor.getEnvelopeKey().getEphemeralKeyPublic(); - final byte[] mac = Base64.getDecoder().decode(encryptedResponse.getMac()); - final byte[] encryptedData = Base64.getDecoder().decode(encryptedResponse.getEncryptedData()); - // TODO: we trust server here, to do not provide nonce in protocols 3.1 and older in response. - final byte[] nonce = encryptedResponse.getNonce() != null ? Base64.getDecoder().decode(encryptedResponse.getNonce()) : requestParameters.getNonce(); - final Long timestamp = encryptedResponse.getTimestamp(); - final EciesCryptogram eciesCryptogramResponse = new EciesCryptogram(ephemeralPublicKey, mac, encryptedData); - - final EciesParameters responseParameters = new EciesParameters(nonce, requestParameters.getAssociatedData(), timestamp); - final EciesPayload payload = new EciesPayload(eciesCryptogramResponse, responseParameters); - - return decryptor.decrypt(payload); - } /** * Creates an encrypted request instance * - * @param eciesPayload Ecies payload data to be sent + * @param encryptedRequest Ecies payload data to be sent * @return Encrypted request instance */ - public static EciesEncryptedRequest createEncryptedRequest(EciesPayload eciesPayload) { + public static EciesEncryptedRequest createEncryptedRequest(EncryptedRequest encryptedRequest) { EciesEncryptedRequest request = new EciesEncryptedRequest(); - final byte[] nonce = eciesPayload.getParameters().getNonce(); - final Long timestamp = eciesPayload.getParameters().getTimestamp(); - request.setEncryptedData(Base64.getEncoder().encodeToString(eciesPayload.getCryptogram().getEncryptedData())); - request.setEphemeralPublicKey(Base64.getEncoder().encodeToString(eciesPayload.getCryptogram().getEphemeralPublicKey())); - request.setMac(Base64.getEncoder().encodeToString(eciesPayload.getCryptogram().getMac())); - request.setNonce(nonce != null ? Base64.getEncoder().encodeToString(nonce) : null); - request.setTimestamp(timestamp); + request.setEncryptedData(encryptedRequest.getEncryptedData()); + request.setEphemeralPublicKey(encryptedRequest.getEphemeralPublicKey()); + request.setMac(encryptedRequest.getMac()); + request.setNonce(encryptedRequest.getNonce()); + request.setTimestamp(encryptedRequest.getTimestamp()); return request; } @@ -149,37 +75,19 @@ public static EciesEncryptedRequest createEncryptedRequest(EciesPayload eciesPay * Process an encrypted response for a step. * @param stepContext Step context. * @param stepId Step identifier. - * @param eciesScope Scope of ECIES. - * @param applicationSecret Application's secret. - * @param associatedData Associated data for ECIES. * @throws Exception Thrown in case response decryption fails. */ - public static void processEncryptedResponse(StepContext stepContext, String stepId, String applicationSecret, EciesScope eciesScope, byte[] associatedData) throws Exception { + public static void processEncryptedResponse(StepContext stepContext, String stepId) throws Exception { ResponseContext responseContext = stepContext.getResponseContext(); SimpleSecurityContext securityContext = (SimpleSecurityContext) stepContext.getSecurityContext(); - EciesEncryptor encryptor = securityContext.getEncryptor(); - - final PowerAuthVersion version = stepContext.getModel().getVersion(); - final String nonce = responseContext.getResponseBodyObject().getNonce(); - final byte[] nonceBytes = version.useDifferentIvForResponse() && nonce != null ? Base64.getDecoder().decode(nonce) : securityContext.getRequestParameters().getNonce(); - final Long timestamp = responseContext.getResponseBodyObject().getTimestamp(); - final byte[] ephemeralPublicKeyBytes = encryptor.getEnvelopeKey().getEphemeralKeyPublic(); - final byte[] transportMasterKeyBytes = eciesScope == EciesScope.ACTIVATION_SCOPE ? Base64.getDecoder().decode(stepContext.getModel().getResultStatus().getTransportMasterKey()) : null; - - EciesParameters eciesParameters = EciesParameters.builder().nonce(nonceBytes).timestamp(timestamp).associatedData(associatedData).build(); - - EciesDecryptor eciesDecryptor; - if (eciesScope == EciesScope.ACTIVATION_SCOPE) { - eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.ACTIVATION_SCOPE, - encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), transportMasterKeyBytes, - eciesParameters, ephemeralPublicKeyBytes); - } else { - eciesDecryptor = ECIES_FACTORY.getEciesDecryptor(EciesScope.APPLICATION_SCOPE, - encryptor.getEnvelopeKey(), applicationSecret.getBytes(StandardCharsets.UTF_8), null, - eciesParameters, ephemeralPublicKeyBytes); - } - final byte[] decryptedBytes = SecurityUtil.decryptBytesFromResponse(eciesDecryptor, responseContext.getResponseBodyObject(), eciesParameters); + EciesEncryptedResponse responseObject = responseContext.getResponseBodyObject(); + final byte[] decryptedBytes = securityContext.getEncryptor().decryptResponse(new EncryptedResponse( + responseObject.getEncryptedData(), + responseObject.getMac(), + responseObject.getNonce(), + responseObject.getTimestamp() + )); String decryptedMessage = new String(decryptedBytes, StandardCharsets.UTF_8); stepContext.getModel().getResultStatus().setResponseData(decryptedMessage); From b1b56cb5385d822743df424b36aaec5f11f423ac Mon Sep 17 00:00:00 2001 From: Jan Dusil <134381434+jandusil@users.noreply.github.com> Date: Thu, 24 Aug 2023 14:17:35 +0200 Subject: [PATCH 37/53] Fix #326: Add CodeQL Analysis (#327) * Fix #326: Add CodeQL Analysis - Add codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..d750a715 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,22 @@ +name: "CodeQL" + +on: + workflow_dispatch: + push: + branches: [ 'develop', 'master', 'releases/**' ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ 'develop', 'master', 'releases/**' ] + schedule: + - cron: '0 2 * * 4' + +jobs: + codeql-analysis: + uses: wultra/wultra-infrastructure/.github/workflows/codeql-analysis.yml@develop + secrets: inherit + with: + languages: "['java']" + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support \ No newline at end of file From eabb5992ae1070a7deeb1c7d0f133240bb6fc842 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 25 Aug 2023 12:47:12 +0200 Subject: [PATCH 38/53] Fix #332: Set release version to 1.5.0 --- pom.xml | 2 +- powerauth-java-cmd-lib/pom.xml | 2 +- powerauth-java-cmd/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index b80473bc..6f8c19e5 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,7 @@ io.getlime.security powerauth-cmd-parent - 1.5.0-SNAPSHOT + 1.5.0 pom 2016 diff --git a/powerauth-java-cmd-lib/pom.xml b/powerauth-java-cmd-lib/pom.xml index c81b505b..16a8385d 100644 --- a/powerauth-java-cmd-lib/pom.xml +++ b/powerauth-java-cmd-lib/pom.xml @@ -10,7 +10,7 @@ powerauth-cmd-parent io.getlime.security - 1.5.0-SNAPSHOT + 1.5.0 diff --git a/powerauth-java-cmd/pom.xml b/powerauth-java-cmd/pom.xml index 4082773a..b1bd4e73 100644 --- a/powerauth-java-cmd/pom.xml +++ b/powerauth-java-cmd/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-cmd-parent - 1.5.0-SNAPSHOT + 1.5.0 From ea2db8c66e55128ac37e4284fb3781c42440ddc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 10:49:10 +0000 Subject: [PATCH 39/53] Bump spring-boot.version from 3.1.2 to 3.1.3 Bumps `spring-boot.version` from 3.1.2 to 3.1.3. Updates `org.springframework.boot:spring-boot-dependencies` from 3.1.2 to 3.1.3 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.2...v3.1.3) Updates `org.springframework.boot:spring-boot-maven-plugin` from 3.1.2 to 3.1.3 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.2...v3.1.3) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b80473bc..cfb293e0 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 3.3.0 3.1.1 3.5.0 - 3.1.2 + 3.1.3 1.76 1.5.0 2.12.0 From 4db2dc55c4c49eeb74f9d903b20e3c4560a25ff7 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 15 Sep 2023 07:54:23 +0200 Subject: [PATCH 40/53] Fix #337: Missing version 3.2 in ComputeOfflineSignatureStep javadoc --- .../powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java index 18e0b5bb..f214d77d 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/ComputeOfflineSignatureStep.java @@ -49,10 +49,9 @@ * *

    PowerAuth protocol versions: *

      - *
    • 2.0
    • - *
    • 2.1
    • *
    • 3.0
    • *
    • 3.1
    • + *
    • 3.2
    • *
    * * @author Roman Strobl, roman.strobl@wultra.com From 23108cf0e4fd5961048118f5525f5dc24812aa1d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 17:36:40 +0000 Subject: [PATCH 41/53] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.5.0...maven-javadoc-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cfb293e0..37bd7043 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 17 3.3.0 3.1.1 - 3.5.0 + 3.6.0 3.1.3 1.76 1.5.0 From 7f5438d42536eaa93ed459a90d76c469e9dbcee5 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 19 Sep 2023 14:17:06 +0200 Subject: [PATCH 42/53] Fix #340: Make lombok dependency scope provided --- pom.xml | 8 ++++++++ powerauth-java-cmd-lib/pom.xml | 6 ------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index cfb293e0..dd925d74 100644 --- a/pom.xml +++ b/pom.xml @@ -112,6 +112,14 @@
    + + + org.projectlombok + lombok + provided + + + diff --git a/powerauth-java-cmd-lib/pom.xml b/powerauth-java-cmd-lib/pom.xml index c81b505b..adceccd7 100644 --- a/powerauth-java-cmd-lib/pom.xml +++ b/powerauth-java-cmd-lib/pom.xml @@ -81,12 +81,6 @@ rest-client-base ${wultra-java-core.version} - - - org.projectlombok - lombok - - From 6199731a93d7e1e7c3bbc976171a45d1eeeb639a Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 19 Sep 2023 14:18:54 +0200 Subject: [PATCH 43/53] Remove travis configuration --- .travis.yml | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0a013614..00000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: java -jdk: - - openjdk11 -branches: - only: - - master - - coverity_scan -env: - global: - - secure: "FXstZjNkkz3f63AnrmGldGwz3ReoWvV1wXclHhJz2CuBFop11PyTXGipMIiRhmxLBLi4whBfta4CeyyzH2loSSYV7GDfdusKp/75WnLXa0Ymzgh/Pcm5get7iXGLzFbJ0MX5bYgjnrPxZh5cynCHkhU+uNl4xFBt9R+7q6Bkb6bKSLMj/7d7wb7i38OBlNRW4hwaMP5EXqJ+42TddNFWKESSsvjK+jW3Qrybu6xdTPiK2pP88SqkZ7JvLU8NpLWLiqpnro3oYs3J45IejPKOZP4R5pW1mS/N9BVhJWG11czpawS1+hBETK0+T6pCmVuql0gJiGE5E23vYGP67kr17PWbj5cfJDE7T/rRz9cqe9DY0/wR3M/1OtstlGK5r68tw02vW2Ew4oWpNi/UvMwsUel4JnSPJmVrL8PGTTkyAqprPYBzAr415Viz51KZ6Fqef2MoY6uHnsB+apsDY3sz9ewJiHDI0sJZAbc3Gysr/xben5eyjN32HTzn1O90xW5sdV+NPbTYmmsSS+aF54pP4qOK0/WQdNou3PyyhoG0/RFx8klZRlADp7pxd6m1cyEsi+9YiUkWbvEHv4m6rSw44pnloyqcb+c89u06Dxq3fhb7dkORX6n4sFkvERYb5UzTEoIbOPP0NQM7q3pssxf1FBqMofJLw4vWgrr/cYoGidM=" - -before_install: - - echo -n | openssl s_client -connect https://scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- - -addons: - coverity_scan: - project: - name: "wultra/powerauth-cmd-tool" - description: "Build submitted via Travis CI" - notification_email: roman.strobl@wultra.com - build_command_prepend: "mvn clean" - build_command: "mvn -DskipTests=true compile" - branch_pattern: coverity_scan From 6984c8f40864caedcb6422147409d2c2d7836c2e Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Wed, 20 Sep 2023 10:08:20 +0200 Subject: [PATCH 44/53] Fix #343: Restrict import of javax.annotation --- pom.xml | 30 +++++++++++++++++++ .../cmd/status/ResultStatusMemoryHolder.java | 2 +- .../lib/cmd/steps/AbstractBaseStep.java | 2 +- .../powerauth/lib/cmd/util/FileUtil.java | 2 +- .../powerauth/lib/cmd/util/HttpUtil.java | 2 +- 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index d344a386..8080824e 100644 --- a/pom.xml +++ b/pom.xml @@ -78,6 +78,7 @@ 3.3.0 3.1.1 3.6.0 + 3.4.1 3.1.3 1.76 1.5.0 @@ -157,6 +158,35 @@ maven-deploy-plugin ${maven-deploy-plugin.version} + + org.apache.maven.plugins + maven-enforcer-plugin + ${maven-enforcer-plugin.version} + + + de.skuzzle.enforcer + restrict-imports-enforcer-rule + 2.4.0 + + + + + enforce-banned-java-imports + + enforce + + + + + + Guava depends on jsr305 but we prefer jakarta in our code + javax.annotation.** + + + + + + diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/status/ResultStatusMemoryHolder.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/status/ResultStatusMemoryHolder.java index 07795dea..1e8f54fd 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/status/ResultStatusMemoryHolder.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/status/ResultStatusMemoryHolder.java @@ -17,9 +17,9 @@ package io.getlime.security.powerauth.lib.cmd.status; import io.getlime.security.powerauth.lib.cmd.steps.pojo.ResultStatusObject; +import jakarta.annotation.Nullable; import org.springframework.stereotype.Component; -import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java index f4a14731..ec2fc039 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/AbstractBaseStep.java @@ -46,6 +46,7 @@ import io.getlime.security.powerauth.lib.cmd.util.*; import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import jakarta.annotation.Nullable; import lombok.Getter; import org.json.simple.JSONObject; import org.slf4j.Logger; @@ -56,7 +57,6 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import javax.annotation.Nullable; import java.util.*; /** diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/FileUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/FileUtil.java index e01fff17..4c332134 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/FileUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/FileUtil.java @@ -18,8 +18,8 @@ import io.getlime.security.powerauth.lib.cmd.exception.PowerAuthCmdException; import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; +import jakarta.annotation.Nullable; -import javax.annotation.Nullable; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/HttpUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/HttpUtil.java index c0f72d81..217dbb36 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/HttpUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/HttpUtil.java @@ -17,9 +17,9 @@ package io.getlime.security.powerauth.lib.cmd.util; import com.fasterxml.jackson.core.JsonProcessingException; +import jakarta.annotation.Nullable; import org.springframework.http.HttpHeaders; -import javax.annotation.Nullable; import java.io.IOException; import java.util.HashMap; import java.util.List; From 724e59db094d849d50380da858b8feab4a5c5fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Wed, 20 Sep 2023 10:28:19 +0200 Subject: [PATCH 45/53] Fix #331: Update to non-snapshot dependencies (#336) * Fix #331: Update to non-snapshot dependencies --- pom.xml | 5 +++-- powerauth-java-cmd-lib/pom.xml | 8 ++++---- .../powerauth/lib/cmd/header/TokenHeaderProvider.java | 7 ++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index b498d7c7..94ebb00f 100644 --- a/pom.xml +++ b/pom.xml @@ -84,8 +84,9 @@ 1.5.0 2.13.0 1.1.1 - 1.5.0-SNAPSHOT - 1.7.0-SNAPSHOT + 1.5.0 + 1.5.1 + 1.7.0 3.1.2 diff --git a/powerauth-java-cmd-lib/pom.xml b/powerauth-java-cmd-lib/pom.xml index adceccd7..e7e82c91 100644 --- a/powerauth-java-cmd-lib/pom.xml +++ b/powerauth-java-cmd-lib/pom.xml @@ -42,17 +42,17 @@ io.getlime.security powerauth-restful-model - ${powerauth.version} + ${powerauth-restful-integration} io.getlime.security powerauth-java-crypto - ${powerauth.version} + ${powerauth-crypto.version} io.getlime.security powerauth-java-http - ${powerauth.version} + ${powerauth-crypto.version} @@ -79,7 +79,7 @@ io.getlime.core rest-client-base - ${wultra-java-core.version} + ${wultra-core.version} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/TokenHeaderProvider.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/TokenHeaderProvider.java index e7b01dc9..e01307a6 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/TokenHeaderProvider.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/header/TokenHeaderProvider.java @@ -44,17 +44,18 @@ public void addHeader(StepContext stepContext) thr String tokenId = model.getTokenId(); byte[] tokenSecret = Base64.getDecoder().decode(model.getTokenSecret()); - ClientTokenGenerator tokenGenerator = new ClientTokenGenerator(); + final ClientTokenGenerator tokenGenerator = new ClientTokenGenerator(); + final String version = model.getVersion().value(); final byte[] tokenNonce = tokenGenerator.generateTokenNonce(); final byte[] tokenTimestamp = tokenGenerator.generateTokenTimestamp(); - final byte[] tokenDigest = tokenGenerator.computeTokenDigest(tokenNonce, tokenTimestamp, tokenSecret); + final byte[] tokenDigest = tokenGenerator.computeTokenDigest(tokenNonce, tokenTimestamp, version, tokenSecret); PowerAuthTokenHttpHeader header = new PowerAuthTokenHttpHeader( tokenId, Base64.getEncoder().encodeToString(tokenDigest), Base64.getEncoder().encodeToString(tokenNonce), new String(tokenTimestamp, StandardCharsets.UTF_8), - model.getVersion().value() + version ); String headerValue = header.buildHttpHeader(); From 2539298bb9cae22b26029eccd513f2f3267995e2 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 21 Sep 2023 15:09:06 +0200 Subject: [PATCH 46/53] Fix #348: Add netty-resolver-dns-native-macos dependency --- powerauth-java-cmd/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/powerauth-java-cmd/pom.xml b/powerauth-java-cmd/pom.xml index 4082773a..350a4d74 100644 --- a/powerauth-java-cmd/pom.xml +++ b/powerauth-java-cmd/pom.xml @@ -57,6 +57,13 @@ ch.qos.logback logback-classic + + + + io.netty + netty-resolver-dns-native-macos + osx-aarch_64 + From 1b7e05cf91020e8238d6a28e4608b9c4a66db68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Thu, 21 Sep 2023 16:00:05 +0200 Subject: [PATCH 47/53] Fix #346: Crypto 3.2: Simplified client configuration (#347) --- docs/Readme.md | 24 ++- .../lib/cmd/consts/PowerAuthVersion.java | 19 +-- .../lib/cmd/steps/VerifySignatureStep.java | 2 - .../lib/cmd/steps/VerifyTokenStep.java | 2 - .../lib/cmd/util/ConfigurationUtil.java | 41 ++++- .../powerauth/lib/cmd/util/CounterUtil.java | 3 +- .../lib/cmd/util/config/DataReader.java | 94 +++++++++++ .../lib/cmd/util/config/DataWriter.java | 93 ++++++++++ .../lib/cmd/util/config/SdkConfiguration.java | 29 ++++ .../config/SdkConfigurationSerializer.java | 96 +++++++++++ .../lib/cmd/util/config/SdkDataReader.java | 159 ++++++++++++++++++ .../lib/cmd/util/config/SdkDataWriter.java | 102 +++++++++++ .../powerauth/app/cmd/Application.java | 80 +++++---- 13 files changed, 681 insertions(+), 63 deletions(-) create mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/DataReader.java create mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/DataWriter.java create mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkConfiguration.java create mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkConfigurationSerializer.java create mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkDataReader.java create mode 100644 powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkDataWriter.java diff --git a/docs/Readme.md b/docs/Readme.md index cff70efc..6c059c1a 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -29,14 +29,12 @@ The command-line tool usually communicates with the Enrollment server component, _Note: You must create this file before you can use the utility. Obtain the information from the PowerAuth Admin interface._ -Client configuration file is required for the correct function of the command-line utility. It contains the same information that would be bundled inside a mobile app after download from the application marketplace. The file stores application key, application secret and master server public key in a following format: +Client configuration file is required for the correct function of the command-line utility. It contains the same information that would be bundled inside a mobile app after download from the application marketplace. The file stores application name and mobile SDK configuration in the following format: ```json { "applicationName": "PowerAuth Reference Client", - "applicationKey": "ivGlm/hl6rn9lSaD4qMgGw==", - "applicationSecret": "bI5pNbDdAXWUr/UQY5+Tpg==", - "masterPublicKey": "BO4+eqJPQTldjcV9G36dGiagsOHzgKgWz5uPuJKYwvIakbFmfWah1N4GXmBOS8aBEwQ+BcV04LL+OBBY0QS1bvg=" + "mobileSdkConfig": "ARCVs2uD4HXnu1uiMLjzv3jUEKhL+EbC7De2hP0CE4QZYMIBAUEEc7WjproYfURYdEDEx7OwSR0A5A+5HNGgUXx8F6eT3KOeIhcsw7tN5PoZN7m3sKutqmUPBrSFqtcDkmQxKTXzlA==" } ``` @@ -44,6 +42,17 @@ You must obtain the values for this file from the PowerAuth Admin interface: ![PowerAuth Admin Preview](./images/pa_admin_application_detail.png) +Note: In case you use an older version of the PowerAuth server which does not contain the mobile SDK configuration parameter, configure the individual parameters in the following format: + +```json +{ + "applicationName": "PowerAuth Reference Client", + "applicationKey": "ivGlm/hl6rn9lSaD4qMgGw==", + "applicationSecret": "bI5pNbDdAXWUr/UQY5+Tpg==", + "masterPublicKey": "BO4+eqJPQTldjcV9G36dGiagsOHzgKgWz5uPuJKYwvIakbFmfWah1N4GXmBOS8aBEwQ+BcV04LL+OBBY0QS1bvg=" +} +``` + ## PowerAuth Client Status File _Note: You should not create this file yourself. The utility creates it for you._ @@ -68,10 +77,9 @@ This file is automatically created by the utility after you call the `create` me ## Specifying PowerAuth Protocol Version Command-line tool supports following PowerAuth protocol versions: -- Version `3.1` (default) +- Version `3.2` (default) +- Version `3.1` - Version `3.0` -- Version `2.1` -- Version `2.0` You can specify the version of protocol you want to use using parameter `version`. Both major and minor version needs to be specified for the command-line tool action, however the server stores only the major version in the database. The version affects used cryptography, for example version `2` activations use custom encryption, while version `3` activations use an integrated ECIES scheme. @@ -448,7 +456,7 @@ If you are using HTTPS, make sure you are using valid SSL certificate or that yo **Error: JCE cannot authenticate the provider BC** -Please use a supported Java Runtime Version (LTS release of Java 8 or 11). +Please use a supported Java Runtime Version (Java 17). ## License diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java index a29718bf..fbada7ca 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/consts/PowerAuthVersion.java @@ -27,16 +27,6 @@ */ public enum PowerAuthVersion { - /** - * Version 2.0 - */ - V2_0(2, "2.0"), - - /** - * Version 2.1 - */ - V2_1(2, "2.1"), - /** * Version 3.0 */ @@ -60,12 +50,7 @@ public enum PowerAuthVersion { /** * Default version */ - public static final PowerAuthVersion DEFAULT = V3_1; - - /** - * All versions belonging to major version 2 - */ - public static final ImmutableList VERSION_2 = ImmutableList.of(V2_0, V2_1); + public static final PowerAuthVersion DEFAULT = V3_2; /** * All versions belonging to major version 3 @@ -78,7 +63,7 @@ public enum PowerAuthVersion { private final int majorVersion; /** - * Version string value ("2.1", "3.0", ...) + * Version string value ("3.0", "3.1", "3.2", ...) */ private final String value; diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java index d05b0a36..a7ab2a68 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifySignatureStep.java @@ -40,8 +40,6 @@ * *

    PowerAuth protocol versions: *

      - *
    • 2.0
    • - *
    • 2.1
    • *
    • 3.0
    • *
    • 3.1
    • *
    • 3.2
    • diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java index 08108370..95414488 100644 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/steps/VerifyTokenStep.java @@ -39,8 +39,6 @@ * *

      PowerAuth protocol versions: *

        - *
      • 2.0
      • - *
      • 2.1
      • *
      • 3.0
      • *
      • 3.1
      • *
      • 3.2
      • diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/ConfigurationUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/ConfigurationUtil.java index d204853b..cadfec6d 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/ConfigurationUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/ConfigurationUtil.java @@ -20,6 +20,7 @@ import io.getlime.security.powerauth.crypto.lib.model.exception.GenericCryptoException; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.lib.cmd.logging.StepLogger; +import io.getlime.security.powerauth.lib.cmd.util.config.SdkConfiguration; import org.json.simple.JSONObject; import java.security.PublicKey; @@ -78,10 +79,45 @@ public static String getApplicationName(JSONObject clientConfigObject) { * @param stepLogger Step logger instance. * @return Master public key. */ - public static PublicKey getMasterKey(JSONObject clientConfigObject, StepLogger stepLogger) { + public static PublicKey getMasterPublicKey(JSONObject clientConfigObject, StepLogger stepLogger) { if (clientConfigObject != null && clientConfigObject.get("masterPublicKey") != null) { + return convertMasterPublicKey((String) clientConfigObject.get("masterPublicKey"), stepLogger); + } + return null; + } + + /** + * Extract master public key from mobile SDK configuration + * @param config Mobile SDK configuration. + * @param stepLogger Step logger instance. + * @return Master public key. + */ + public static PublicKey getMasterPublicKey(SdkConfiguration config, StepLogger stepLogger) { + return convertMasterPublicKey(config.masterPublicKeyBase64(), stepLogger); + } + + /** + * Get mobile SDK configuration. + * @param clientConfigObject Object with configuration. + * @return Mobile SKD configuration. + */ + public static String getMobileSdkConfig(JSONObject clientConfigObject) { + if (clientConfigObject.get("mobileSdkConfig") != null) { + return (String) clientConfigObject.get("mobileSdkConfig"); + } + return null; + } + + /** + * Convert master public key from String to PublicKey + * @param masterPublicKey Master public key + * @param stepLogger Step logger + * @return Public key + */ + private static PublicKey convertMasterPublicKey(String masterPublicKey, StepLogger stepLogger) { + if (masterPublicKey != null) { try { - byte[] masterKeyBytes = Base64.getDecoder().decode((String) clientConfigObject.get("masterPublicKey")); + byte[] masterKeyBytes = Base64.getDecoder().decode(masterPublicKey); return keyConvertor.convertBytesToPublicKey(masterKeyBytes); } catch (IllegalArgumentException e) { stepLogger.writeError("master-key-error-encoding", "Invalid Master Server Public Key", "Master Server Public Key must be stored in a valid Base64 encoding", e); @@ -107,5 +143,4 @@ public static PublicKey getMasterKey(JSONObject clientConfigObject, StepLogger s } return null; } - } diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java index b7f9a35e..4a7ea59b 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/CounterUtil.java @@ -83,8 +83,7 @@ public static byte[] getCtrData(ResultStatusObject resultStatusObject, StepLogge } /** - * Increment counter value in step model. In version 2.0 and 2.1 only numeric counter is incremented. In version - * 3.0 the counter data is incremented using hash based counter, too. + * Increment counter value in step model. * * @param model Step model. */ diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/DataReader.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/DataReader.java new file mode 100644 index 00000000..845743bd --- /dev/null +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/DataReader.java @@ -0,0 +1,94 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2023 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +package io.getlime.security.powerauth.lib.cmd.util.config; + +/** + * Data reader interface for PowerAuth mobile SDK, see: + * https://github.com/wultra/powerauth-mobile-sdk/blob/develop/src/PowerAuth/utils/DataReader.h + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public interface DataReader { + + /** + * Resets data reader to its initial state. + */ + void reset(); + + /** + * Returns remaining size available in the stream. + * @return Remaining size. + */ + int remainingSize(); + + /** + * Returns current reading offset. + * @return Current reading offset. + */ + int currentOffset(); + + /** + * Returns true if it's possible to read at least |size| of bytes from stream. + * @param size Byte size. + * @return True if reader can read next bytes. + */ + boolean canReadSize(int size); + + /** + * Skips required number of bytes in the stream. Returns false, if there's not enough bytes left. + * @param size Byte size. + * @return True if skip was successful. + */ + boolean skipBytes(int size); + + /** + * Reads a data object into output byte array. + * @param expectedSize Expected byte array size or 0 for any size. + * @return Read data. + */ + byte[] readData(int expectedSize); + + /** + * Reads a string object into output byte array. + * @return Read string. + */ + String readString(); + + /** + * Reads an exact number of bytes into output byte array. Unlike the {@link #readData(int)} method, this method + * reads just exact number of bytes from the stream, without any size marker. + * @param size Byte size. + * @return Read bytes. + */ + byte[] readRaw(int size); + + /** + * Reads one byte into output byte array. + * @return Read byte. + */ + Byte readByte(); + + /** + * Returns count from data stream. + * @return Count. + */ + Integer readCount(); + +} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/DataWriter.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/DataWriter.java new file mode 100644 index 00000000..e161eaa5 --- /dev/null +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/DataWriter.java @@ -0,0 +1,93 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2023 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +package io.getlime.security.powerauth.lib.cmd.util.config; + +/** + * Data writer interface for PowerAuth mobile SDK, see: + * https://github.com/wultra/powerauth-mobile-sdk/blob/develop/src/PowerAuth/utils/DataWriter.h + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public interface DataWriter { + + /** + * Resets data writer object to its initial state. + */ + void reset(); + + /** + * Writes one byte to the stream. + * @param b Byte to write. + */ + void writeByte(byte b); + + /** + * Writes number of bytes in byte range and actual + * data to the stream. The size of range must not exceed + * value returned from {@link #getMaxCount()} method. + * @param bytes Bytes to write. + */ + void writeData(byte[] bytes); + + /** + * Writes number of characters in string and actual content + * of string to the data stream. The length of string must + * not exceed value returned from {@link #getMaxCount()} method. + * @param str String to write. + */ + void writeString(String str); + + /** + * Writes only the content of byte range to the data stream. + * Unlike the {@link #writeData(byte[])}, this method doesn't store number of bytes + * as a size marker. It's up to you, how you determine the size + * of sequence during the data reading. + * @param bytes Data bytes. + */ + void writeRaw(byte[] bytes); + + /** + * Writes a count to the stream in optimized binary format. The count + * parameter must be less or equal than value returned from + * {@link #getMaxCount()} method. + * + * You should prefer this method for counter-type values over the writing + * 32-bit or 64-bit values to the stream, because it usually produces a shorter byte + * streams. For example, if count value is lesser than 128, then just + * one byte is serialized. + * @param count Count value to write. + */ + boolean writeCount(int count); + + /** + * Returns serialized data. + * @return Serialized data. + */ + byte[] getSerializedData(); + + /** + * Returns maximum supported value which can be serialized as + * a counter. The returned value is the same for all supported + * platforms and CPU architectures. + * @return Maximum count value. + */ + int getMaxCount(); + +} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkConfiguration.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkConfiguration.java new file mode 100644 index 00000000..b883debe --- /dev/null +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkConfiguration.java @@ -0,0 +1,29 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2023 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +package io.getlime.security.powerauth.lib.cmd.util.config; + +/** + * Parameters for configuring PowerAuth Mobile SDK. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public record SdkConfiguration(String appKeyBase64, String appSecretBase64, String masterPublicKeyBase64) { + +} \ No newline at end of file diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkConfigurationSerializer.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkConfigurationSerializer.java new file mode 100644 index 00000000..d9e8e738 --- /dev/null +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkConfigurationSerializer.java @@ -0,0 +1,96 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2023 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +package io.getlime.security.powerauth.lib.cmd.util.config; + +import org.springframework.util.StringUtils; + +import java.util.Base64; + +/** + * Writer for serialized PowerAuth mobile SDK configuration. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public class SdkConfigurationSerializer { + + private static final byte SDK_CONFIGURATION_VERSION = 0x01; + private static final byte MASTER_PUBLIC_KEY_CRYPTO_V3 = 0x01; + + /** + * Serialize SDK configuration into a single Base-64 encoded string. + * @param config SDK configuration. + * @return Base-64 encoded string. + */ + public static String serialize(SdkConfiguration config) { + final String appKeyBase64 = config.appKeyBase64(); + final String appSecretBase64 = config.appSecretBase64(); + final String masterPublicKeyBase64 = config.masterPublicKeyBase64(); + if (!StringUtils.hasText(appKeyBase64)) { + throw new IllegalArgumentException("Invalid application key"); + } + if (!StringUtils.hasText(appSecretBase64)) { + throw new IllegalArgumentException("Invalid application secret"); + } + if (!StringUtils.hasText(masterPublicKeyBase64)) { + throw new IllegalArgumentException("Invalid public key"); + } + final SdkDataWriter writer = new SdkDataWriter(); + writer.writeByte(SDK_CONFIGURATION_VERSION); + writer.writeData(Base64.getDecoder().decode(appKeyBase64)); + writer.writeData(Base64.getDecoder().decode(appSecretBase64)); + writer.writeCount(1); + writer.writeByte(MASTER_PUBLIC_KEY_CRYPTO_V3); + final byte[] publicKeyBytes = Base64.getDecoder().decode(masterPublicKeyBase64); + writer.writeData(publicKeyBytes); + return Base64.getEncoder().encodeToString(writer.getSerializedData()); + } + + /** + * Deserialize SDK configuration from a Base-64 encoded string. + * @param serialized Serialized SDK configuration. + * @return SDK configuration. + */ + public static SdkConfiguration deserialize(String serialized) { + final byte[] serializedBytes = Base64.getDecoder().decode(serialized); + final SdkDataReader reader = new SdkDataReader(serializedBytes); + final Byte version = reader.readByte(); + if (version == null || version != SDK_CONFIGURATION_VERSION) { + return null; + } + final byte[] appKey = reader.readData(16); + final byte[] appSecret = reader.readData(16); + final Integer keyCount = reader.readCount(); + if (appKey == null || appSecret == null || keyCount != 1) { + // Unexpected data + return null; + } + final Byte keyId = reader.readByte(); + if (keyId != 0x01) { + // Invalid key ID + return null; + } + final byte[] masterPublicKey = reader.readData(0); + final String appKeyBase64 = Base64.getEncoder().encodeToString(appKey); + final String appSecretBase64 = Base64.getEncoder().encodeToString(appSecret); + final String masterPublicKeyBase64 = Base64.getEncoder().encodeToString(masterPublicKey); + return new SdkConfiguration(appKeyBase64, appSecretBase64, masterPublicKeyBase64); + } + +} \ No newline at end of file diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkDataReader.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkDataReader.java new file mode 100644 index 00000000..446fa782 --- /dev/null +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkDataReader.java @@ -0,0 +1,159 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2023 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +package io.getlime.security.powerauth.lib.cmd.util.config; + +import lombok.extern.slf4j.Slf4j; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +/** + * Data reader implementation for PowerAuth mobile SDK, see: + * https://github.com/wultra/powerauth-mobile-sdk/blob/develop/src/PowerAuth/utils/DataReader.cpp + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@Slf4j +public class SdkDataReader implements DataReader { + + private final byte[] data; + private int offset = 0; + + /** + * SDK reader constructor. + * @param data Binary data to read. + */ + public SdkDataReader(byte[] data) { + this.data = data; + } + + @Override + public void reset() { + this.offset = 0; + } + + @Override + public int remainingSize() { + return data.length - offset; + } + + @Override + public int currentOffset() { + return offset; + } + + @Override + public boolean canReadSize(int size) { + return remainingSize() >= size; + } + + @Override + public boolean skipBytes(int size) { + if (!canReadSize(size)) { + return false; + } + offset += size; + return true; + } + + @Override + public byte[] readData(int expectedSize) { + final Integer size = readCount(); + if (size == null) { + return null; + } + if (!canReadSize(size)) { + return null; + } + if (expectedSize > 0 && expectedSize != size) { + return null; + } + byte[] result = Arrays.copyOfRange(data, offset, offset + size); + offset += size; + return result; + } + + @Override + public String readString() { + final Integer size = readCount(); + if (size == null) { + return null; + } + if (!canReadSize(size)) { + return null; + } + final byte[] strData = Arrays.copyOfRange(data, offset, offset + size); + offset += size; + return new String(strData, StandardCharsets.UTF_8); + } + + @Override + public byte[] readRaw(int size) { + if (!canReadSize(size)) { + return null; + } + final byte[] result = Arrays.copyOfRange(data, offset, offset + size); + offset += size; + return result; + } + + @Override + public Byte readByte() { + if (!canReadSize(1)) { + return null; + } + byte result = data[offset]; + offset++; + return result; + } + + @Override + public Integer readCount() { + final Byte firstByte = readByte(); + if (firstByte == null) { + return null; + } + final int byte1u = Byte.toUnsignedInt(firstByte); + final int marker = byte1u & 0xC0; + if (marker == 0x00 || marker == 0x40) { + return byte1u; + } + // marker is 2 or 3, that means that we need 1 or 3 more bytes + final int additionalByteCount = marker == 0xC0 ? 3 : 1; + final byte[] remainingBytes = readRaw(additionalByteCount); + if (remainingBytes == null) { + return null; + } + final int byte2u = Byte.toUnsignedInt(remainingBytes[0]); + if (marker == 0xC0) { + // 4 bytes + int byte3u = Byte.toUnsignedInt(remainingBytes[1]); + int byte4u = Byte.toUnsignedInt(remainingBytes[2]); + return (byte1u & 0x3F) << 24 | + byte2u << 16 | + byte3u << 8 | + byte4u; + } else { + // 2 bytes + return (byte1u & 0x3F) << 8 | + byte2u; + } + } +} diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkDataWriter.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkDataWriter.java new file mode 100644 index 00000000..2b06eb83 --- /dev/null +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/config/SdkDataWriter.java @@ -0,0 +1,102 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2023 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +package io.getlime.security.powerauth.lib.cmd.util.config; + +import lombok.extern.slf4j.Slf4j; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/** + * Data writer implementation for PowerAuth mobile SDK, see: + * https://github.com/wultra/powerauth-mobile-sdk/blob/develop/src/PowerAuth/utils/DataWriter.cpp + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public class SdkDataWriter implements DataWriter { + + private final ByteArrayOutputStream os = new ByteArrayOutputStream(); + + @Override + public void reset() { + os.reset(); + } + + @Override + public void writeByte(byte b) { + os.write(b); + } + + @Override + public void writeData(byte[] bytes) { + if (!writeCount(bytes.length)) { + return; + } + writeRaw(bytes); + } + + @Override + public void writeString(String str) { + writeData(str.getBytes(StandardCharsets.UTF_8)); + } + + @Override + public void writeRaw(byte[] bytes) { + try { + os.write(bytes); + } catch (IOException e) { + } + } + + @Override + public boolean writeCount(int count) { + // The SDK expects unsigned values, convert int to unsigned long for the byte operations + if (count < 0) { + return false; + } + long n = Integer.toUnsignedLong(count); + if (n <= 0x7F) { + writeByte((byte) n); + } else if (n <= 0x3FFF) { + writeByte((byte) (((n >> 8 ) & 0x3F) | 0x80)); + writeByte((byte) (n & 0xFF)); + } else if (n <= 0x3FFFFFFF) { + writeByte((byte) (((n >> 24) & 0x3F) | 0xC0)); + writeByte((byte) ((n >> 16) & 0xFF)); + writeByte((byte) ((n >> 8 ) & 0xFF)); + writeByte((byte) (n & 0xFF)); + } else { + return false; + } + return true; + } + + @Override + public byte[] getSerializedData() { + return os.toByteArray(); + } + + @Override + public int getMaxCount() { + return 0x3FFFFFFF; + } + +} \ No newline at end of file diff --git a/powerauth-java-cmd/src/main/java/io/getlime/security/powerauth/app/cmd/Application.java b/powerauth-java-cmd/src/main/java/io/getlime/security/powerauth/app/cmd/Application.java index bf919312..1be24180 100755 --- a/powerauth-java-cmd/src/main/java/io/getlime/security/powerauth/app/cmd/Application.java +++ b/powerauth-java-cmd/src/main/java/io/getlime/security/powerauth/app/cmd/Application.java @@ -31,6 +31,8 @@ import io.getlime.security.powerauth.lib.cmd.util.FileUtil; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; import io.getlime.security.powerauth.lib.cmd.util.RestClientFactory; +import io.getlime.security.powerauth.lib.cmd.util.config.SdkConfiguration; +import io.getlime.security.powerauth.lib.cmd.util.config.SdkConfigurationSerializer; import org.apache.commons.cli.*; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.json.simple.JSONObject; @@ -194,7 +196,27 @@ public static void main(String[] args) { clientConfigObject = new JSONObject(configAttributes); // Read master public key - PublicKey masterPublicKey = ConfigurationUtil.getMasterKey(clientConfigObject, stepLogger); + final String mobileSdkConfig = ConfigurationUtil.getMobileSdkConfig(clientConfigObject); + final String applicationKey; + final String applicationSecret; + final PublicKey masterPublicKey; + if (mobileSdkConfig != null) { + // Extract simplified mobile SDK configuration + final SdkConfiguration config = SdkConfigurationSerializer.deserialize(mobileSdkConfig); + if (config == null) { + stepLogger.writeError("invalid-sdk-config", "Invalid Mobile SDK Config", "Mobile SDK Config is not valid"); + stepLogger.writeDoneFailed("sdk-config-failed"); + System.exit(1); + } + applicationKey = config.appKeyBase64(); + applicationSecret = config.appSecretBase64(); + masterPublicKey = ConfigurationUtil.getMasterPublicKey(config, stepLogger); + } else { + // Fallback to traditional mobile SDK configuration + applicationKey = ConfigurationUtil.getApplicationKey(clientConfigObject); + applicationSecret = ConfigurationUtil.getApplicationSecret(clientConfigObject); + masterPublicKey = ConfigurationUtil.getMasterPublicKey(clientConfigObject, stepLogger); + } // Read current activation state from the activation state file or create an empty state ResultStatusObject resultStatusObject; @@ -219,8 +241,8 @@ public static void main(String[] args) { case TOKEN_CREATE -> { CreateTokenStepModel model = new CreateTokenStepModel(); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setMasterPublicKey(masterPublicKey); model.setPassword(cmd.getOptionValue("p")); @@ -254,8 +276,8 @@ public static void main(String[] args) { case TOKEN_REMOVE -> { RemoveTokenStepModel model = new RemoveTokenStepModel(); model.setTokenId(cmd.getOptionValue("T")); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setMasterPublicKey(masterPublicKey); model.setPassword(cmd.getOptionValue("p")); @@ -279,8 +301,8 @@ public static void main(String[] args) { model.setActivationName(ConfigurationUtil.getApplicationName(clientConfigObject)); model.setPlatform(platform); model.setDeviceInfo(deviceInfo); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setMasterPublicKey(masterPublicKey); model.setPassword(cmd.getOptionValue("p")); @@ -304,8 +326,8 @@ public static void main(String[] args) { case ACTIVATION_REMOVE -> { RemoveStepModel model = new RemoveStepModel(); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setPassword(cmd.getOptionValue("p")); model.setResultStatus(resultStatusObject); @@ -318,8 +340,8 @@ public static void main(String[] args) { case SIGNATURE_VERIFY -> { VerifySignatureStepModel model = new VerifySignatureStepModel(); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setHttpMethod(cmd.getOptionValue("t")); model.setPassword(cmd.getOptionValue("p")); @@ -341,8 +363,8 @@ public static void main(String[] args) { case VAULT_UNLOCK -> { VaultUnlockStepModel model = new VaultUnlockStepModel(); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setPassword(cmd.getOptionValue("p")); model.setResultStatus(resultStatusObject); @@ -369,8 +391,8 @@ public static void main(String[] args) { model.setPlatform(platform); model.setDeviceInfo(deviceInfo); model.setActivationOtp(cmd.getOptionValue("a")); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setCustomAttributes(customAttributes); model.setHeaders(httpHeaders); model.setIdentityAttributes(identityAttributes); @@ -385,8 +407,8 @@ public static void main(String[] args) { } case ENCRYPT -> { EncryptStepModel model = new EncryptStepModel(); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setDryRun(cmd.hasOption("dry-run")); model.setHeaders(httpHeaders); model.setMasterPublicKey(masterPublicKey); @@ -404,8 +426,8 @@ public static void main(String[] args) { } case SIGN_ENCRYPT -> { VerifySignatureStepModel model = new VerifySignatureStepModel(); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setHttpMethod(cmd.getOptionValue("t")); model.setPassword(cmd.getOptionValue("p")); @@ -427,8 +449,8 @@ public static void main(String[] args) { TokenAndEncryptStepModel model = new TokenAndEncryptStepModel(); model.setTokenId(cmd.getOptionValue("T")); model.setTokenSecret(cmd.getOptionValue("S")); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHttpMethod(cmd.getOptionValue("t")); model.setDryRun(cmd.hasOption("dry-run")); model.setHeaders(httpHeaders); @@ -445,8 +467,8 @@ public static void main(String[] args) { } case UPGRADE_START -> { StartUpgradeStepModel model = new StartUpgradeStepModel(); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setStatusFileName(statusFileName); model.setResultStatus(resultStatusObject); @@ -457,8 +479,8 @@ public static void main(String[] args) { } case UPGRADE_COMMIT -> { CommitUpgradeStepModel model = new CommitUpgradeStepModel(); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setStatusFileName(statusFileName); model.setResultStatus(resultStatusObject); @@ -480,8 +502,8 @@ public static void main(String[] args) { model.setActivationName(ConfigurationUtil.getApplicationName(clientConfigObject)); model.setPlatform(platform); model.setDeviceInfo(deviceInfo); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setIdentityAttributes(identityAttributes); model.setCustomAttributes(customAttributes); model.setHeaders(httpHeaders); @@ -497,8 +519,8 @@ public static void main(String[] args) { case RECOVERY_CONFIRM -> { ConfirmRecoveryCodeStepModel model = new ConfirmRecoveryCodeStepModel(); - model.setApplicationKey(ConfigurationUtil.getApplicationKey(clientConfigObject)); - model.setApplicationSecret(ConfigurationUtil.getApplicationSecret(clientConfigObject)); + model.setApplicationKey(applicationKey); + model.setApplicationSecret(applicationSecret); model.setHeaders(httpHeaders); model.setMasterPublicKey(masterPublicKey); model.setStatusFileName(statusFileName); From 7cf132b5bb801bd389627f2c9bdb0c39ad41f538 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 22 Sep 2023 07:36:12 +0200 Subject: [PATCH 48/53] Fix #350: Exclude lombok from jar --- powerauth-java-cmd/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/powerauth-java-cmd/pom.xml b/powerauth-java-cmd/pom.xml index a731fd51..1af2087a 100644 --- a/powerauth-java-cmd/pom.xml +++ b/powerauth-java-cmd/pom.xml @@ -82,6 +82,12 @@ io.getlime.security.powerauth.app.cmd.Application + + + org.projectlombok + lombok + + From 469e49ccc586871fb5c7c2e3750f31e9daf78b2e Mon Sep 17 00:00:00 2001 From: "roman.strobl@wultra.com" Date: Fri, 22 Sep 2023 08:49:09 +0200 Subject: [PATCH 49/53] Update supported Java versions --- docs/Readme.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/Readme.md b/docs/Readme.md index 6c059c1a..87375316 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -11,9 +11,10 @@ You can download the latest `powerauth-java-cmd.jar` at the releases page: ## Supported Java Runtime Versions The following Java runtime versions are supported: -- Java 17 (LTS release) or higher +- OpenJDK 17 (LTS release) or higher +- Oracle Java is not supported, please use OpenJDK. -Older Java versions are currently not supported due to migration to Spring Boot 3 +Older Java versions are currently not supported due to migration to Spring Boot 3. ## Bouncy Castle Library Usage @@ -456,7 +457,9 @@ If you are using HTTPS, make sure you are using valid SSL certificate or that yo **Error: JCE cannot authenticate the provider BC** -Please use a supported Java Runtime Version (Java 17). +Please use a supported Java Runtime Version (OpenJDK 17 or higher, not Oracle Java). + +See: https://github.com/wultra/powerauth-cmd-tool/issues/232#issuecomment-1730848437 ## License From 6bd29b9a328962d009aad7c36c41595664d20143 Mon Sep 17 00:00:00 2001 From: "roman.strobl@wultra.com" Date: Fri, 22 Sep 2023 11:34:38 +0200 Subject: [PATCH 50/53] Fix #354: Incompatibility with PowerAuth stack 1.4.x --- .../powerauth/lib/cmd/util/RestClientConfiguration.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/RestClientConfiguration.java b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/RestClientConfiguration.java index 7685d06c..0ae24d52 100755 --- a/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/RestClientConfiguration.java +++ b/powerauth-java-cmd-lib/src/main/java/io/getlime/security/powerauth/lib/cmd/util/RestClientConfiguration.java @@ -16,6 +16,7 @@ */ package io.getlime.security.powerauth.lib.cmd.util; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -32,6 +33,7 @@ public class RestClientConfiguration { static { mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationFeature.USE_LONG_FOR_INTS, true); From 89e9eacfdb990837904d1ba63eadcb3767e9306b Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 25 Sep 2023 12:49:57 +0200 Subject: [PATCH 51/53] Fix #357: Improve documentation of Validate Token Use an existing endpoint instead of misleading general prefix. Retrieving list is easier than creating and approving operation. --- docs/Readme.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/Readme.md b/docs/Readme.md index 87375316..f7369cd5 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -219,11 +219,11 @@ _Note: If a `--password` option is not provided, this method requires interactiv ### Validate Token -Use a previously created token to authorize an operation. +Use a previously created token to retrieve a list of operations. ```bash java -jar powerauth-java-cmd.jar \ - --url "http://localhost:8080/enrollment-server/api/auth/token" \ + --url "http://localhost:8080/enrollment-server/api/auth/token/app/operation/list" \ --status-file "/tmp/pa_status.json" \ --config-file "/tmp/pamk.json" \ --method "validate-token" \ @@ -233,7 +233,9 @@ java -jar powerauth-java-cmd.jar \ --token-secret "xfb1NUXAPbvDZK8qyNVGyw==" ``` -Uses the `validate-token` method for an activation with activation ID stored in the status file `/tmp/pa_status.json`, by calling an endpoint `/api/auth/token` hosted on root URL `http://localhost:8080/enrollment-server`. The endpoint must be published by the application -- see [Token Based Authentication](https://github.com/wultra/powerauth-restful-integration/blob/develop/docs/RESTful-API-for-Spring.md#use-token-based-authentication). Uses the application identifiers stored in the `/tmp/pamk.json` file. The request data is taken from file `/tmp/request.json`. +Uses the `validate-token` method for an activation with activation ID stored in the status file `/tmp/pa_status.json`, by calling an endpoint `/api/auth/token/app/operation/list` hosted on root URL `http://localhost:8080/enrollment-server`. +The endpoint must be published by the application -- see [Token Based Authentication](https://github.com/wultra/powerauth-restful-integration/blob/develop/docs/RESTful-API-for-Spring.md#use-token-based-authentication). Uses the application identifiers stored in the `/tmp/pamk.json` file. +The request data is taken from file `/tmp/request.json`. You can use the `dry-run` parameter, in this case the step is stopped right after signing the request body and preparing appropriate headers. From 312ab0cc8287fa19d876a930bb1d3ffa569a54b8 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 25 Sep 2023 14:08:56 +0200 Subject: [PATCH 52/53] Rephrase operation/list into an example --- docs/Readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/Readme.md b/docs/Readme.md index f7369cd5..a70b2cea 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -219,7 +219,9 @@ _Note: If a `--password` option is not provided, this method requires interactiv ### Validate Token -Use a previously created token to retrieve a list of operations. +Token validation may be performed against any endpoint using [Token Based Authentication](https://github.com/wultra/powerauth-restful-integration/blob/develop/docs/RESTful-API-for-Spring.md#use-token-based-authentication). + +For example, use the previously created token to retrieve a list of operations. ```bash java -jar powerauth-java-cmd.jar \ @@ -234,7 +236,7 @@ java -jar powerauth-java-cmd.jar \ ``` Uses the `validate-token` method for an activation with activation ID stored in the status file `/tmp/pa_status.json`, by calling an endpoint `/api/auth/token/app/operation/list` hosted on root URL `http://localhost:8080/enrollment-server`. -The endpoint must be published by the application -- see [Token Based Authentication](https://github.com/wultra/powerauth-restful-integration/blob/develop/docs/RESTful-API-for-Spring.md#use-token-based-authentication). Uses the application identifiers stored in the `/tmp/pamk.json` file. +Uses the application identifiers stored in the `/tmp/pamk.json` file. The request data is taken from file `/tmp/request.json`. You can use the `dry-run` parameter, in this case the step is stopped right after signing the request body and preparing appropriate headers. From 4e6ae38041f7cde854b9d28b5d6a542346aaaadb Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 25 Sep 2023 14:57:46 +0200 Subject: [PATCH 53/53] Fix #359: Remove version 2 from documentation --- docs/Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Readme.md b/docs/Readme.md index 87375316..1af6c46d 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -82,7 +82,8 @@ Command-line tool supports following PowerAuth protocol versions: - Version `3.1` - Version `3.0` -You can specify the version of protocol you want to use using parameter `version`. Both major and minor version needs to be specified for the command-line tool action, however the server stores only the major version in the database. The version affects used cryptography, for example version `2` activations use custom encryption, while version `3` activations use an integrated ECIES scheme. +You can specify the version of protocol you want to use using parameter `version`. Both major and minor version needs to be specified for the command-line tool action, however the server stores only the major version in the database. +The version affects used cryptography, for example version `3` activations use an integrated ECIES scheme. ## Supported Use-Cases @@ -284,7 +285,6 @@ There is a required format of both `identity.json` and `custom-attributes.json` _Note: If a `--password` option is not provided, this method requires interactive console input of the password, in order to encrypt the knowledge related signature key._ -_Note: In protocol version `2.x` you need to provide a full URL in `--url` parameter, pointing to the custom activation endpoint._ ### Send Encrypted Data to Server