diff --git a/build.gradle b/build.gradle index 8324ba688..cae425366 100644 --- a/build.gradle +++ b/build.gradle @@ -48,7 +48,7 @@ dependencies { implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${openApiVersion}" implementation group: 'com.smartsensesolutions', name: 'commons-dao', version: '0.0.5' implementation 'org.liquibase:liquibase-core' - implementation 'org.eclipse.tractusx.ssi:cx-ssi-lib:0.0.6' + implementation 'org.eclipse.tractusx.ssi:cx-ssi-lib:0.0.7' runtimeOnly 'org.postgresql:postgresql' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java index 4214085e3..4cb65dba9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java @@ -29,8 +29,6 @@ import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import java.net.URLDecoder; -import java.nio.charset.Charset; import java.util.List; /** @@ -66,16 +64,6 @@ public class Wallet extends MIWBaseEntity { @Convert(converter = StringToDidDocumentConverter.class) private DidDocument didDocument; - @Transient private List verifiableCredentials; - - /** - * Sets did. - * - * @param did the did - */ - public void setDid(String did) { - this.did = URLDecoder.decode(did, Charset.defaultCharset()); - } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java index 9f3fb8ad2..e11928839 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java @@ -29,6 +29,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.WalletNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; +import org.eclipse.tractusx.ssi.lib.exception.DidParseException; import org.springframework.stereotype.Service; @Service @@ -49,7 +50,12 @@ public Wallet getWalletByIdentifier(String identifier) { if (CommonUtils.getIdentifierType(identifier).equals(StringPool.BPN)) { wallet = walletRepository.getByBpn(identifier); } else { - wallet = walletRepository.getByDid(identifier); + try { + wallet = walletRepository.getByDid(identifier); + } catch (DidParseException e) { + log.error("Error while parsing did {}", identifier, e); + throw new WalletNotFoundProblem("Error while parsing did " + identifier); + } } Validate.isNull(wallet).launch(new WalletNotFoundProblem("Wallet not found for identifier " + identifier)); return wallet; 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 664cff8dc..78b04f8aa 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -104,11 +104,11 @@ public PageImpl getCredentials(String credentialId, String //Holder must be caller of API Wallet holderWallet = commonService.getWalletByIdentifier(callerBPN); - filterRequest.appendCriteria(StringPool.HOLDER_DID, Operator.EQUALS, holderWallet.getDid()); + filterRequest.appendCriteria(StringPool.HOLDER_DID, Operator.EQUALS, holderWallet.getDid().toString()); if (StringUtils.hasText(issuerIdentifier)) { Wallet issuerWallet = commonService.getWalletByIdentifier(issuerIdentifier); - filterRequest.appendCriteria(StringPool.ISSUER_DID, Operator.EQUALS, issuerWallet.getDid()); + filterRequest.appendCriteria(StringPool.ISSUER_DID, Operator.EQUALS, issuerWallet.getDid().toString()); } if (StringUtils.hasText(credentialId)) { 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 88ba6c81f..1b48564ce 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -46,6 +46,8 @@ import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; +import org.eclipse.tractusx.ssi.lib.did.resolver.DidDocumentResolverRegistry; +import org.eclipse.tractusx.ssi.lib.did.resolver.DidDocumentResolverRegistryImpl; import org.eclipse.tractusx.ssi.lib.did.web.DidWebDocumentResolver; import org.eclipse.tractusx.ssi.lib.did.web.util.DidWebParser; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; @@ -53,8 +55,7 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofValidation; -import org.eclipse.tractusx.ssi.lib.resolver.DidDocumentResolverRegistry; -import org.eclipse.tractusx.ssi.lib.resolver.DidDocumentResolverRegistryImpl; +import org.eclipse.tractusx.ssi.lib.proof.SignatureType; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.stereotype.Service; @@ -187,9 +188,11 @@ public PageImpl getCredentials(String credentialId, String public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, + VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, StringPool.ID, holderWallet.getDid(), - StringPool.BPN, holderWallet.getBpn()), types, baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), authority); + StringPool.BPN, holderWallet.getBpn())); + HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(verifiableCredentialSubject, + types, baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), authority); //Store Credential in holder wallet holdersCredential = holdersCredentialRepository.save(holdersCredential); @@ -231,12 +234,12 @@ public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialReq //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); - Map subject = Map.of( + VerifiableCredentialSubject subject = new VerifiableCredentialSubject(Map.of( StringPool.TYPE, request.getType(), StringPool.ID, holderWallet.getDid(), StringPool.HOLDER_IDENTIFIER, holderWallet.getBpn(), StringPool.CONTRACT_TEMPLATE, request.getContractTemplate(), - StringPool.CONTRACT_VERSION, request.getContractVersion()); + StringPool.CONTRACT_VERSION, request.getContractVersion())); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(subject, types, baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); @@ -282,11 +285,11 @@ public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialR //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(request.getBpn()); - Map subject = Map.of(StringPool.TYPE, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, + VerifiableCredentialSubject subject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, StringPool.ID, holderWallet.getDid(), StringPool.HOLDER_IDENTIFIER, holderWallet.getBpn(), StringPool.ACTIVITY_TYPE, request.getActivityType(), - StringPool.ALLOWED_VEHICLE_BRANDS, request.getAllowedVehicleBrands()); + StringPool.ALLOWED_VEHICLE_BRANDS, request.getAllowedVehicleBrands())); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(subject, types, issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); @@ -335,12 +338,13 @@ public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialR boolean isSelfIssued = isSelfIssued(issueMembershipCredentialRequest.getBpn()); //VC Subject - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(Map.of(StringPool.TYPE, VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, + VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, StringPool.ID, holderWallet.getDid(), StringPool.HOLDER_IDENTIFIER, holderWallet.getBpn(), StringPool.MEMBER_OF, issuerWallet.getName(), StringPool.STATUS, "Active", - StringPool.START_TIME, Instant.now().toString()), types, issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); + StringPool.START_TIME, Instant.now().toString())); + HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(verifiableCredentialSubject, types, issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); //save in holder wallet @@ -423,8 +427,21 @@ public Map credentialsValidation(Map data) { didDocumentResolverRegistry.register( new DidWebDocumentResolver(HttpClient.newHttpClient(), new DidWebParser(), miwSettings.enforceHttps())); - LinkedDataProofValidation proofValidation = LinkedDataProofValidation.newInstance(didDocumentResolverRegistry); - Boolean valid = proofValidation.checkProof(verifiableCredential); + String proofTye = verifiableCredential.getProof().get(StringPool.TYPE).toString(); + LinkedDataProofValidation proofValidation; + if (SignatureType.ED21559.toString().equals(proofTye)) { + proofValidation = LinkedDataProofValidation.newInstance( + SignatureType.ED21559, + didDocumentResolverRegistry); + } else if (SignatureType.JWS.toString().equals(proofTye)) { + proofValidation = LinkedDataProofValidation.newInstance( + SignatureType.JWS, + didDocumentResolverRegistry); + } else { + throw new BadDataException(String.format("Invalid proof type: %s", proofTye)); + } + + Boolean valid = proofValidation.verifiyProof(verifiableCredential); Map response = new HashMap<>(); response.put(StringPool.VALID, valid); response.put("vc", verifiableCredential); @@ -482,6 +499,7 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, byte[] issu } } else { items = List.of(type); + } } else { items = List.of(type); @@ -500,11 +518,11 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, byte[] issu //issue new summery VC boolean isSelfIssued = isSelfIssued(holderBpn); - Map subject = Map.of(StringPool.ID, holderDid, + VerifiableCredentialSubject subject = new VerifiableCredentialSubject(Map.of(StringPool.ID, holderDid, StringPool.HOLDER_IDENTIFIER, holderBpn, StringPool.ITEMS, items, StringPool.TYPE, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL, - StringPool.CONTRACT_TEMPLATES, miwSettings.contractTemplatesUrl()); + StringPool.CONTRACT_TEMPLATES, miwSettings.contractTemplatesUrl())); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(subject, types, 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 215822e5c..cb90cef86 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -36,8 +36,14 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; +import org.eclipse.tractusx.ssi.lib.crypt.ed25519.Ed25519Key; +import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; +import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; +import org.eclipse.tractusx.ssi.lib.did.resolver.DidDocumentResolverRegistry; +import org.eclipse.tractusx.ssi.lib.did.resolver.DidDocumentResolverRegistryImpl; import org.eclipse.tractusx.ssi.lib.did.web.DidWebDocumentResolver; import org.eclipse.tractusx.ssi.lib.did.web.util.DidWebParser; +import org.eclipse.tractusx.ssi.lib.exception.InvalidePrivateKeyFormat; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtValidator; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; @@ -47,9 +53,6 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; -import org.eclipse.tractusx.ssi.lib.resolver.DidDocumentResolverRegistry; -import org.eclipse.tractusx.ssi.lib.resolver.DidDocumentResolverRegistryImpl; -import org.eclipse.tractusx.ssi.lib.resolver.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.serialization.jsonLd.JsonLdSerializerImpl; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactory; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactoryImpl; @@ -98,19 +101,18 @@ protected SpecificationUtil getSpecificationUtil() { * @param callerBpn the caller bpn * @return the map */ + @SneakyThrows({InvalidePrivateKeyFormat.class}) public Map createPresentation(Map data, boolean asJwt, String audience, String callerBpn) { List> verifiableCredentialList = (List>) data.get(StringPool.VERIFIABLE_CREDENTIALS); //only support one credential at a time to create VP Validate.isTrue(verifiableCredentialList.size() > 1).launch(new BadDataException("Only one credentials is supported to create presentation")); - String holderIdentifier = data.get(StringPool.HOLDER_IDENTIFIER).toString(); - //check if holder wallet is in the system - Wallet holderWallet = commonService.getWalletByIdentifier(holderIdentifier); + Wallet callerWallet = commonService.getWalletByIdentifier(callerBpn); //validate BPN access - Issuer(Creator) of VP must be caller Issuer of VP must be holder of VC - Validate.isFalse(holderWallet.getBpn().equalsIgnoreCase(callerBpn)).launch(new ForbiddenException("Holder identifier is not matching with request BPN(from the token)")); + Validate.isFalse(callerWallet.getBpn().equalsIgnoreCase(callerBpn)).launch(new ForbiddenException("Holder identifier is not matching with request BPN(from the token)")); List verifiableCredentials = new ArrayList<>(verifiableCredentialList.size()); verifiableCredentialList.forEach(map -> { @@ -124,15 +126,17 @@ public Map createPresentation(Map data, boolean Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); //Issuer of VP is holder of VC - Did vpIssuerDid = DidParser.parse(holderWallet.getDid()); + Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); //JWT Factory SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), vpIssuerDid); //Build JWT + Ed25519Key ed25519Key = walletKeyService.getPrivateKeyByWalletIdentifier(callerWallet.getId()); + x21559PrivateKey privateKey = new x21559PrivateKey(ed25519Key.getEncoded()); SignedJWT presentation = presentationFactory.createPresentation(vpIssuerDid - , verifiableCredentials, audience, walletKeyService.getPrivateKeyByWalletIdentifier(holderWallet.getId())); + , verifiableCredentials, audience, privateKey); response.put(StringPool.VP, presentation.serialize()); } else { 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 ca5b7ba7f..0965fee24 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -27,7 +27,7 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.bouncycastle.util.io.pem.PemReader; +import org.bouncycastle.util.encoders.Base64; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; @@ -60,7 +60,6 @@ protected SpecificationUtil getSpecificationUtil() { return specificationUtil; } - /** * Get private key by wallet identifier as bytes byte [ ]. * @@ -83,7 +82,7 @@ public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId) { public Ed25519Key getPrivateKeyByWalletIdentifier(long walletId) { WalletKey wallet = walletKeyRepository.getByWalletId(walletId); String privateKey = encryptionUtils.decrypt(wallet.getPrivateKey()); - byte[] content = new PemReader(new StringReader(privateKey)).readPemObject().getContent(); + byte[] content = Base64.decode(privateKey); return Ed25519Key.asPrivateKey(content); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java index 3bb927460..77300b0d5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.service; +import com.google.crypto.tink.subtle.Base64; import com.smartsensesolutions.java.commons.FilterRequest; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; import com.smartsensesolutions.java.commons.base.service.BaseService; @@ -31,14 +32,11 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator; -import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters; import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; -import org.bouncycastle.crypto.util.PrivateKeyInfoFactory; -import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; -import org.bouncycastle.openssl.jcajce.JcaPEMWriter; +import org.bouncycastle.crypto.util.PrivateKeyFactory; +import org.bouncycastle.crypto.util.PublicKeyFactory; +import org.bouncycastle.jcajce.provider.asymmetric.edec.KeyPairGeneratorSpi; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; @@ -52,10 +50,10 @@ import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; -import org.eclipse.tractusx.ssi.lib.base.MultibaseFactory; import org.eclipse.tractusx.ssi.lib.crypt.ed25519.Ed25519KeySet; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.MultibaseString; +import org.eclipse.tractusx.ssi.lib.model.base.MultibaseFactory; import org.eclipse.tractusx.ssi.lib.model.did.*; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; @@ -65,10 +63,9 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -import java.io.StringWriter; -import java.net.URLDecoder; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; @@ -133,7 +130,7 @@ public Map storeCredential(Map data, String iden holdersCredentialRepository.save(HoldersCredential.builder() .holderDid(wallet.getDid()) - .issuerDid(URLDecoder.decode(verifiableCredential.getIssuer().toString(), Charset.defaultCharset())) + .issuerDid(verifiableCredential.getIssuer().toString()) .type(String.join(",", cloneTypes)) .data(verifiableCredential) .selfIssued(false) @@ -212,12 +209,11 @@ public Wallet createWallet(CreateWalletRequest request) { private Wallet createWallet(CreateWalletRequest request, boolean authority) { validateCreateWallet(request); - //create private key pair Ed25519KeySet keyPair = createKeyPair(); //create did json - Did did = DidWebFactory.fromHostname(miwSettings.host() + ":" + request.getBpn()); + Did did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), request.getBpn()); //Extracting keys Ed25519KeySet keySet = new Ed25519KeySet(keyPair.getPrivateKey(), keyPair.getPublicKey()); @@ -225,8 +221,8 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority) { //Building Verification Methods: List verificationMethods = new ArrayList<>(); - Ed25519VerificationKey2020Builder builder = new Ed25519VerificationKey2020Builder(); - Ed25519VerificationKey2020 key = + Ed25519VerificationMethodBuilder builder = new Ed25519VerificationMethodBuilder(); + Ed25519VerificationMethod key = builder .id(did.toUri()) .controller(did.toUri()) @@ -238,7 +234,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority) { didDocumentBuilder.id(did.toUri()); didDocumentBuilder.verificationMethods(verificationMethods); DidDocument didDocument = didDocumentBuilder.build(); - didDocument = DidDocument.fromJson(URLDecoder.decode(didDocument.toJson(), StandardCharsets.UTF_8)); + didDocument = DidDocument.fromJson(didDocument.toJson()); log.debug("did document created for bpn ->{}", request.getBpn()); //Save wallet @@ -246,7 +242,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority) { .didDocument(didDocument) .bpn(request.getBpn()) .name(request.getName()) - .did(URLDecoder.decode(did.toUri().toString(), Charset.defaultCharset())) + .did(did.toUri().toString()) .algorithm(StringPool.ED_25519) .build()); @@ -296,37 +292,30 @@ private void validateCreateWallet(CreateWalletRequest request) { @SneakyThrows private Ed25519KeySet createKeyPair() { - SecureRandom secureRandom = new SecureRandom(); - - Ed25519KeyPairGenerator keyPairGenerator = new Ed25519KeyPairGenerator(); - keyPairGenerator.init(new Ed25519KeyGenerationParameters(secureRandom)); - - AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair(); - Ed25519PrivateKeyParameters privateKey = (Ed25519PrivateKeyParameters) keyPair.getPrivate(); - Ed25519PublicKeyParameters publicKey = (Ed25519PublicKeyParameters) keyPair.getPublic(); - - byte[] privateKeyBytes = privateKey.getEncoded(); - byte[] publicKeyBytes = publicKey.getEncoded(); + KeyPairGeneratorSpi.Ed25519 ed25519 = new KeyPairGeneratorSpi.Ed25519(); + ed25519.initialize(256, new SecureRandom()); + KeyPair keyPair = ed25519.generateKeyPair(); + PublicKey PubKey = keyPair.getPublic(); + PrivateKey PivKey = keyPair.getPrivate(); + Ed25519PrivateKeyParameters ed25519PrivateKeyParameters = + (Ed25519PrivateKeyParameters) PrivateKeyFactory.createKey(PivKey.getEncoded()); + Ed25519PublicKeyParameters publicKeyParameters = + (Ed25519PublicKeyParameters) PublicKeyFactory.createKey(PubKey.getEncoded()); + + byte[] privateKeyBytes = ed25519PrivateKeyParameters.getEncoded(); + byte[] publicKeyBytes = publicKeyParameters.getEncoded(); return new Ed25519KeySet(privateKeyBytes, publicKeyBytes); } @SneakyThrows private String getPrivateKeyString(byte[] privateKeyBytes) { - StringWriter stringWriter = new StringWriter(); - JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter); - pemWriter.writeObject(PrivateKeyInfoFactory.createPrivateKeyInfo(new Ed25519PrivateKeyParameters(privateKeyBytes, 0))); - pemWriter.close(); - return stringWriter.toString(); + return Base64.encode(privateKeyBytes); } @SneakyThrows private String getPublicKeyString(byte[] publicKeyBytes) { - StringWriter stringWriter = new StringWriter(); - JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter); - pemWriter.writeObject(SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(new Ed25519PublicKeyParameters(publicKeyBytes, 0))); - pemWriter.close(); - return stringWriter.toString(); + return Base64.encode(publicKeyBytes); } } 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 637885a92..f2d84a0cd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -21,22 +21,22 @@ package org.eclipse.tractusx.managedidentitywallets.utils; +import lombok.SneakyThrows; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; -import org.eclipse.tractusx.ssi.lib.model.Ed25519Signature2020; +import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; +import org.eclipse.tractusx.ssi.lib.exception.InvalidePrivateKeyFormat; +import org.eclipse.tractusx.ssi.lib.exception.UnsupportedSignatureTypeException; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.proof.Proof; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofGenerator; -import org.eclipse.tractusx.ssi.lib.proof.hash.LinkedDataHasher; -import org.eclipse.tractusx.ssi.lib.proof.transform.LinkedDataTransformer; -import org.eclipse.tractusx.ssi.lib.proof.verify.LinkedDataSigner; +import org.eclipse.tractusx.ssi.lib.proof.SignatureType; import java.net.URI; -import java.net.URLDecoder; -import java.nio.charset.Charset; import java.time.Instant; import java.util.*; @@ -74,25 +74,20 @@ public static String getIdentifierType(String identifier) { * @param holderDid the holder did * @return the credential */ - public static HoldersCredential getHoldersCredential(Map subject, List types, DidDocument issuerDoc, + public static HoldersCredential getHoldersCredential(VerifiableCredentialSubject subject, List types, DidDocument issuerDoc, byte[] privateKeyBytes, String holderDid, List contexts, Date expiryDate, boolean selfIssued) { - //VC Subject - VerifiableCredentialSubject verifiableCredentialSubject = - new VerifiableCredentialSubject(subject); - - List cloneTypes = new ArrayList<>(types); // Create VC VerifiableCredential verifiableCredential = createVerifiableCredential(issuerDoc, types, - verifiableCredentialSubject, privateKeyBytes, contexts, expiryDate); + subject, privateKeyBytes, contexts, expiryDate); - cloneTypes.remove(VerifiableCredentialType.VERIFIABLE_CREDENTIAL); + cloneTypes.remove(VerifiableCredentialType.VERIFIABLE_CREDENTIAL); // Create Credential return HoldersCredential.builder() .holderDid(holderDid) - .issuerDid(URLDecoder.decode(issuerDoc.getId().toString(), Charset.defaultCharset())) + .issuerDid(issuerDoc.getId().toString()) .type(String.join(",", cloneTypes)) .credentialId(verifiableCredential.getId().toString()) .data(verifiableCredential) @@ -100,28 +95,28 @@ public static HoldersCredential getHoldersCredential(Map subject .build(); } - + @SneakyThrows({UnsupportedSignatureTypeException.class, InvalidePrivateKeyFormat.class}) private static VerifiableCredential createVerifiableCredential(DidDocument issuerDoc, List verifiableCredentialType, VerifiableCredentialSubject verifiableCredentialSubject, byte[] privateKey, List contexts, Date expiryDate) { //VC Builder + URI id = URI.create(UUID.randomUUID().toString()); VerifiableCredentialBuilder builder = new VerifiableCredentialBuilder() .context(contexts) - .id(URI.create(UUID.randomUUID().toString())) + .id(id) .type(verifiableCredentialType) .issuer(issuerDoc.getId()) .expirationDate(expiryDate.toInstant()) .issuanceDate(Instant.now()) .credentialSubject(verifiableCredentialSubject); - //Ed25519 Proof Builder - LinkedDataProofGenerator generator = new LinkedDataProofGenerator( - new LinkedDataHasher(), new LinkedDataTransformer(), new LinkedDataSigner()); + LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.ED21559); URI verificationMethod = issuerDoc.getVerificationMethods().get(0).getId(); - Ed25519Signature2020 proof = generator.createEd25519Signature2020(builder.build(), verificationMethod, - privateKey); + VerifiableCredential credential = builder.build(); + Proof proof = generator.createProof(credential, verificationMethod, + new x21559PrivateKey(privateKey)); //Adding Proof to VC builder.proof(proof); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToDidDocumentConverter.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToDidDocumentConverter.java index 93c7bac4f..87ac6f807 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToDidDocumentConverter.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToDidDocumentConverter.java @@ -36,7 +36,7 @@ public class StringToDidDocumentConverter implements AttributeConverter