diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index 11d6ece1e..199f29121 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -31,13 +31,21 @@ @Repository public interface WalletKeyRepository extends BaseRepository { /** - * Gets by wallet id. + * Gets by wallet id and algorithm. * * @param id the id + * param algorithm the algorithm * @return the by wallet id */ WalletKey getByWalletIdAndAlgorithm(Long id, String algorithm); + /** + * Gets by wallet id. + * @param id + * @return WalletKey + */ + WalletKey getByWalletId(Long id); + WalletKey findFirstByWallet_Bpn(String bpn); WalletKey findFirstByWallet_Did(String did); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index af31c3e62..b78b2f18e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -160,7 +160,7 @@ public CredentialsResponse issueCredential(Map data, boolean asJ Validate.isFalse(callerBpn.equals(issuerWallet.getBpn())).launch(new ForbiddenException(BASE_WALLET_BPN_IS_NOT_MATCHING_WITH_REQUEST_BPN_FROM_TOKEN)); // get Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); // check if the expiryDate is set Date expiryDate = null; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java index 40193247e..dde4f231e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -190,7 +190,7 @@ public PageImpl getCredentials(GetCredentialsCommand comman */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, StringPool.ID, holderWallet.getDid(), @@ -233,7 +233,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ validateAccess(callerBPN, baseWallet); // get Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); @@ -293,7 +293,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe //check duplicate isCredentialExit(holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(request.getBpn()); @@ -352,7 +352,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe validateAccess(callerBPN, issuerWallet); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, VerifiableCredentialType.MEMBERSHIP_CREDENTIAL); //if base wallet issue credentials to itself @@ -417,7 +417,7 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< validateAccess(callerBpn, issuerWallet); // get issuer Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java index 70b57fac8..6f66ec5bd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -146,9 +146,8 @@ public Map createPresentation(Map data, boolean return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, SupportedAlgorithms.ED25519); } - @SneakyThrows({ InvalidePrivateKeyFormat.class }) private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, - List verifiableCredentials, SupportedAlgorithms algorithm) { + List verifiableCredentials, SupportedAlgorithms algorithm){ Map response = new HashMap<>(); if (asJwt && algorithm.equals(SupportedAlgorithms.ES256K)) { buildVPJwtES256K(audience, callerBpn, callerWallet, verifiableCredentials, algorithm, response); @@ -174,15 +173,16 @@ private void buildVPJsonLd(String callerBpn, List verifiab response.put(StringPool.VP, verifiablePresentation); } - private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) throws InvalidePrivateKeyFormat { + @SneakyThrows({ InvalidPrivateKeyFormatException.class}) + private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) { Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), result.getKey()); - x21559PrivateKey ed25519Key = (x21559PrivateKey) result.getRight(); - x21559PrivateKey privateKey = new x21559PrivateKey(ed25519Key.asByte()); - SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey); + x25519PrivateKey ed25519Key = (x25519PrivateKey) result.getRight(); + x25519PrivateKey privateKey = new x25519PrivateKey(ed25519Key.asByte()); + SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey , "keyId" ); response.put(StringPool.VP, presentation.serialize()); } @@ -197,6 +197,7 @@ private void buildVPJwtES256K(String audience, String callerBpn, Wallet callerWa response.put(StringPool.VP, presentation.serialize()); } + @SneakyThrows({ DidParseException.class }) private Pair getPrivateKey(Wallet callerWallet, SupportedAlgorithms algorithm, String audience, String callerBpn) { log.debug("Creating VP as JWT for bpn ->{}", callerBpn); Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); @@ -205,7 +206,7 @@ private Pair getPrivateKey(Wallet callerWallet, SupportedAlgorithms Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); //Build JWT - return Pair.of(vpIssuerDid, walletKeyService.getPrivateKeyByWalletIdentifierAndAlgorithm(callerWallet.getId(), algorithm)); + return Pair.of(vpIssuerDid, walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(callerWallet.getId(), algorithm)); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 6883fb2de..0453a0c6f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -69,13 +69,14 @@ protected SpecificationUtil getSpecificationUtil() { * Get private key by wallet identifier as bytes byte [ ]. * * @param walletId the wallet id + * @param algorithm the algorithm * @return the byte [ ] */ @SneakyThrows - public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId, String algorithm) { - Object privateKey = getPrivateKeyByWalletIdentifierAndAlgorithm(walletId, SupportedAlgorithms.valueOf(algorithm)); - if (privateKey instanceof x21559PrivateKey x21559PrivateKey) { - return x21559PrivateKey.asByte(); + public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { + Object privateKey = getPrivateKeyByWalletIdAndAlgorithm(walletId, SupportedAlgorithms.valueOf(algorithm)); + if (privateKey instanceof x25519PrivateKey x25519PrivateKey) { + return x25519PrivateKey.asByte(); } else { return ((ECPrivateKey) privateKey).getEncoded(); } @@ -85,16 +86,16 @@ public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId, String algor * Gets private key by wallet identifier. * * @param walletId the wallet id + * @param algorithm the algorithm * @return the private key by wallet identifier */ @SneakyThrows - - public Object getPrivateKeyByWalletIdentifierAndAlgorithm(long walletId, SupportedAlgorithms algorithm) { + public Object getPrivateKeyByWalletIdAndAlgorithm(long walletId, SupportedAlgorithms algorithm) { WalletKey wallet = walletKeyRepository.getByWalletIdAndAlgorithm(walletId, algorithm.toString()); String privateKey = encryptionUtils.decrypt(wallet.getPrivateKey()); byte[] content = new PemReader(new StringReader(privateKey)).readPemObject().getContent(); if (SupportedAlgorithms.ED25519.equals(algorithm)) { - return new x21559PrivateKey(content); + return new x25519PrivateKey(content); } else if (SupportedAlgorithms.ES256K.equals(algorithm)) { KeyFactory kf = KeyFactory.getInstance(EC); return kf.generatePrivate(new PKCS8EncodedKeySpec(content)); @@ -103,4 +104,16 @@ public Object getPrivateKeyByWalletIdentifierAndAlgorithm(long walletId, Support } } + /** + * Gets wallet key by wallet identifier. + * + * @param walletId the wallet id + * @return the wallet key by wallet identifier + */ + @SneakyThrows + public String getWalletKeyIdByWalletId(long walletId) { + return walletKeyRepository.getByWalletId(walletId).getKeyId(); + } + + } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java index 8dc13570f..360f2ae7b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -27,6 +27,7 @@ import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -35,6 +36,7 @@ import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.exception.json.TransformJsonLdException; import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureGenerateFailedException; @@ -182,7 +184,8 @@ public static SecureTokenRequest getSecureTokenRequest(MultiValueMap vpResponse = createBpnVCAsJwt(bpn, audience); @@ -159,7 +160,7 @@ void validateVPAsJwtWithInvalidSignatureAndInValidAudienceAndExpiryDateValidatio } @Test - void validateVPAsJwtWithValidAudienceAndDateValidation() throws JsonProcessingException { + void validateVPAsJwtWithValidAudienceAndDateValidation() throws JsonProcessingException, JSONException { //create VP String bpn = TestUtils.getRandomBpmNumber(); String audience = "companyA"; @@ -176,7 +177,7 @@ void validateVPAsJwtWithValidAudienceAndDateValidation() throws JsonProcessingEx } @Test - void validateVPAsJwtWithInValidVCDateValidation() throws JsonProcessingException { + void validateVPAsJwtWithInValidVCDateValidation() throws JsonProcessingException, JSONException { //create VP String bpn = TestUtils.getRandomBpmNumber(); String audience = "companyA"; @@ -194,7 +195,7 @@ void validateVPAsJwtWithInValidVCDateValidation() throws JsonProcessingException } @Test - void createPresentationAsJWT201() throws JsonProcessingException, ParseException { + void createPresentationAsJWT201() throws JsonProcessingException, ParseException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); String audience = "companyA"; @@ -209,7 +210,7 @@ void createPresentationAsJWT201() throws JsonProcessingException, ParseException Assertions.assertEquals(iss, did); } - private ResponseEntity createBpnVCAsJwt(String bpn, String audience) throws JsonProcessingException { + private ResponseEntity createBpnVCAsJwt(String bpn, String audience) throws JsonProcessingException, JSONException { Map request = getIssueVPRequest(bpn); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); @@ -223,7 +224,7 @@ private ResponseEntity createBpnVCAsJwt(String bpn, String audience) throws @Test - void createPresentationAsJsonLD201() throws JsonProcessingException { + void createPresentationAsJsonLD201() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String didWeb = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); @@ -241,7 +242,7 @@ void createPresentationAsJsonLD201() throws JsonProcessingException { } @Test - void createPresentationWithInvalidBPNAccess403() throws JsonProcessingException { + void createPresentationWithInvalidBPNAccess403() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String didWeb = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); @@ -257,7 +258,7 @@ void createPresentationWithInvalidBPNAccess403() throws JsonProcessingException } @NotNull - private Map getIssueVPRequest(String bpn) throws JsonProcessingException { + private Map getIssueVPRequest(String bpn) throws JsonProcessingException, JSONException { String baseBpn = miwSettings.authorityWalletBpn(); String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); @@ -278,7 +279,7 @@ private Map getIssueVPRequest(String bpn) throws JsonProcessingE } @NotNull - private ResponseEntity getIssueVPRequestWithShortExpiry(String bpn, String audience) throws JsonProcessingException { + private ResponseEntity getIssueVPRequestWithShortExpiry(String bpn, String audience) throws JsonProcessingException, JSONException { String baseBpn = miwSettings.authorityWalletBpn(); String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java index 1beac2a56..92062d791 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -315,7 +315,7 @@ void storeCredentialsWithDifferentHolder403() throws JsonProcessingException { } @Test - void createWalletWithDuplicateBpn409() throws JsonProcessingException { + void createWalletWithDuplicateBpn409() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Wallet"; @@ -362,7 +362,7 @@ void getWalletByIdentifierWithInvalidBPNTest403() { } @Test - void getWalletByIdentifierBPNTest200() throws JsonProcessingException { + void getWalletByIdentifierBPNTest200() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Name"; String baseBpn = miwSettings.authorityWalletBpn(); @@ -386,7 +386,7 @@ void getWalletByIdentifierBPNTest200() throws JsonProcessingException { @Test - void getWalletByIdentifierBPNWithCredentialsTest200() throws JsonProcessingException { + void getWalletByIdentifierBPNWithCredentialsTest200() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Name"; String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); @@ -416,7 +416,7 @@ void getWalletByIdentifierBPNWithCredentialsTest200() throws JsonProcessingExcep @Test @Disabled("the endpoint has an issue that prevents resolving did with a port number") - void getWalletByIdentifierDidTest200() throws JsonProcessingException { + void getWalletByIdentifierDidTest200() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Name"; @@ -462,7 +462,7 @@ void getWallets403() { @Test - void getWallets200() throws JsonProcessingException { + void getWallets200() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Name"; @@ -535,7 +535,7 @@ private ResponseEntity storeCredential(String bpn, String did) throws JsonP } - private List getWalletsFromString(String body) throws JsonProcessingException { + private List getWalletsFromString(String body) throws JsonProcessingException, JSONException { List walletList = new ArrayList<>(); JSONArray array = new JSONArray(new JSONObject(body).getJSONArray("content"));