Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Create VC as JWT #260

Merged
Merged
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b604f3d
fix: add asJwt to controllers and services
mustafasalfiti Feb 27, 2024
1b260fa
fix: exceptions
mustafasalfiti Feb 27, 2024
61832ed
fix: exception names
mustafasalfiti Feb 27, 2024
d0522f4
fix: did resolver
mustafasalfiti Feb 27, 2024
ef961a5
fix: add asJwt as query param and fix exceptions
mustafasalfiti Mar 5, 2024
7f01263
fix: part of tests
mustafasalfiti Mar 5, 2024
bb0b30c
fix: current tests
mustafasalfiti Mar 5, 2024
842e437
fix: add test and validation
mustafasalfiti Mar 12, 2024
4216e0d
fix: get vc as jwt with tests
mustafasalfiti Mar 19, 2024
2154b7f
fix: add copyright to getCredentialsCommand
mustafasalfiti Mar 19, 2024
4aec527
fix: add wiremock
mustafasalfiti Mar 19, 2024
531d3f7
fix: add exceptions and fix naming
mustafasalfiti Apr 19, 2024
8b5180a
fix: test for jwt
mustafasalfiti Apr 19, 2024
3da1eff
fix: update code with the new ssi lib main
mustafasalfiti Apr 19, 2024
760ee94
fix: api docs
mustafasalfiti Apr 19, 2024
069a7d3
fix: add keyId to createPresentation
mustafasalfiti Apr 22, 2024
fa9ee4b
fix: change context url
mustafasalfiti Apr 23, 2024
02b1f5a
fix: update ssi agent lib version
mustafasalfiti Apr 24, 2024
b840c77
fix: remove try catch
mustafasalfiti Apr 24, 2024
0c5f111
fix: remove new line
mustafasalfiti Apr 24, 2024
14f6195
fix: revert IssueDismantlerCredentialReqeust.java
mustafasalfiti Apr 24, 2024
050358e
fix: add asJwt to controllers and services
mustafasalfiti Feb 27, 2024
fc6c077
fix: exceptions
mustafasalfiti Feb 27, 2024
30a60d5
fix: exception names
mustafasalfiti Feb 27, 2024
8cbb756
fix: add asJwt as query param and fix exceptions
mustafasalfiti Mar 5, 2024
50ba388
fix: part of tests
mustafasalfiti Mar 5, 2024
b3db3e0
fix: add test and validation
mustafasalfiti Mar 12, 2024
dba48e2
fix: add exceptions and fix naming
mustafasalfiti Apr 19, 2024
0a69f1c
fix: test for jwt
mustafasalfiti Apr 19, 2024
9497d3e
fix: update code with the new ssi lib main
mustafasalfiti Apr 19, 2024
8e7b796
fix: api docs
mustafasalfiti Apr 19, 2024
874e850
fix: remove try catch
mustafasalfiti Apr 24, 2024
31819c8
fix: remove new line
mustafasalfiti Apr 24, 2024
bac5200
fix: revert IssueDismantlerCredentialReqeust.java
mustafasalfiti Apr 24, 2024
697ff85
fix: formatting
nitin-vavdiya May 23, 2024
e00620d
fix: formatting
nitin-vavdiya May 23, 2024
956b6af
fix: copyright updated
nitin-vavdiya May 23, 2024
9ade90e
fix: copyright updated
nitin-vavdiya May 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: add test and validation
  • Loading branch information
mustafasalfiti authored and nitin-vavdiya committed May 14, 2024
commit 842e4375ac68567fddcfa648d75d1e98eaa0e0d4
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ public class StringPool {
public static final String ALLOWED_VEHICLE_BRANDS = "allowedVehicleBrands";
public static final String VERIFIABLE_CREDENTIALS = "verifiableCredentials";
public static final String VP = "vp";
public static final String VC = "vc";
public static final String VALID = "valid";
public static final String VALIDATE_AUDIENCE = "validateAudience";
public static final String VALIDATE_EXPIRY_DATE = "validateExpiryDate";
Original file line number Diff line number Diff line change
@@ -21,6 +21,8 @@

package org.eclipse.tractusx.managedidentitywallets.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jwt.SignedJWT;
import com.smartsensesolutions.java.commons.FilterRequest;
import com.smartsensesolutions.java.commons.base.repository.BaseRepository;
import com.smartsensesolutions.java.commons.base.service.BaseService;
@@ -29,6 +31,8 @@
import com.smartsensesolutions.java.commons.sort.Sort;
import com.smartsensesolutions.java.commons.sort.SortType;
import com.smartsensesolutions.java.commons.specification.SpecificationUtil;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringEscapeUtils;
@@ -40,6 +44,7 @@
import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet;
import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository;
import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository;
import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest;
import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse;
import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest;
import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest;
@@ -52,11 +57,15 @@
import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver;
import org.eclipse.tractusx.ssi.lib.did.web.DidWebResolver;
import org.eclipse.tractusx.ssi.lib.did.web.util.DidWebParser;
import org.eclipse.tractusx.ssi.lib.exception.proof.JwtExpiredException;
import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtValidator;
import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier;
import org.eclipse.tractusx.ssi.lib.model.did.DidDocument;
import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential;
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.serialization.SerializeUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
@@ -66,7 +75,9 @@
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.net.http.HttpClient;
import java.text.ParseException;
import java.time.Instant;
import java.util.*;

@@ -75,6 +86,7 @@
*/
@Service
@Slf4j
@RequiredArgsConstructor
public class IssuersCredentialService extends BaseService<IssuersCredential, Long> {

/**
@@ -93,26 +105,7 @@ public class IssuersCredentialService extends BaseService<IssuersCredential, Lon

private final CommonService commonService;

/**
* Instantiates a new Issuers credential service.
*
* @param issuersCredentialRepository the issuers credential repository
* @param miwSettings the miw settings
* @param credentialSpecificationUtil the credential specification util
* @param walletKeyService the wallet key service
* @param holdersCredentialRepository the holders credential repository
* @param commonService the common service
*/
public IssuersCredentialService(IssuersCredentialRepository issuersCredentialRepository, MIWSettings miwSettings,
SpecificationUtil<IssuersCredential> credentialSpecificationUtil,
WalletKeyService walletKeyService, HoldersCredentialRepository holdersCredentialRepository, CommonService commonService) {
this.issuersCredentialRepository = issuersCredentialRepository;
this.miwSettings = miwSettings;
this.credentialSpecificationUtil = credentialSpecificationUtil;
this.walletKeyService = walletKeyService;
this.holdersCredentialRepository = holdersCredentialRepository;
this.commonService = commonService;
}
private final ObjectMapper objectMapper;


@Override
@@ -449,31 +442,105 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map<

return cr;
}


private JWTVerificationResult verifyVCAsJWT(String jwt, DidResolver didResolver, boolean withCredentialsValidation, boolean withCredentialExpiryDate) throws IOException, ParseException {
SignedJWT signedJWT = SignedJWT.parse(jwt);
Map<String, Object> claims = objectMapper.readValue(signedJWT.getPayload().toBytes(), Map.class);
String vcClaim = objectMapper.writeValueAsString(claims.get("vc"));
Map<String, Object> map = SerializeUtil.fromJson(vcClaim);
VerifiableCredential verifiableCredential = new VerifiableCredential(map);

//took this approach to avoid issues in sonarQube
return new JWTVerificationResult(validateSignature(withCredentialsValidation , signedJWT, didResolver) && validateJWTExpiryDate(withCredentialExpiryDate, signedJWT), verifiableCredential);

}

private record JWTVerificationResult(boolean valid, VerifiableCredential verifiableCredential) {

}

private boolean validateSignature(boolean withValidateSignature, SignedJWT signedJWT, DidResolver didResolver) {
if(!withValidateSignature) {
return true;
}
//validate jwt signature
try {
SignedJwtVerifier jwtVerifier = new SignedJwtVerifier(didResolver);
return jwtVerifier.verify(signedJWT);
} catch (Exception e) {
log.error("Can not verify signature of jwt", e);
return false;
}
}
private boolean validateJWTExpiryDate(boolean withExpiryDate , SignedJWT signedJWT) {
if(!withExpiryDate) {
return true;
}
try {
SignedJwtValidator jwtValidator = new SignedJwtValidator();
jwtValidator.validateDate(signedJWT);
return true;
} catch (Exception e) {
if (!(e instanceof JwtExpiredException)) {
log.error("Can not validate jwt expiry date ", e);
}
return false;
}
}

/**
* Credentials validation map.
*
* @param verificationRequest the verifiable credential
* @param withCredentialExpiryDate the with credential expiry date
* @return the map
*/
public Map<String, Object> credentialsValidation(CredentialVerificationRequest verificationRequest, boolean withCredentialExpiryDate) {
return credentialsValidation(verificationRequest, true, withCredentialExpiryDate);
}

/**
* Credentials validation map.
*
* @param data the data
* @param withCredentialExpiryDate the with credential expiry date
* @return the map
*/
@SneakyThrows
public Map<String, Object> credentialsValidation(Map<String, Object> data, boolean withCredentialExpiryDate) {
VerifiableCredential verifiableCredential = new VerifiableCredential(data);
public Map<String, Object> credentialsValidation(CredentialVerificationRequest verificationRequest, boolean withCredentialsValidation , boolean withCredentialExpiryDate) {
HttpClient httpClient = HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.ALWAYS)
.build();

DidResolver didResolver = new DidWebResolver(HttpClient.newHttpClient(), new DidWebParser(), miwSettings.enforceHttps());
DidResolver didResolver = new DidWebResolver(httpClient, new DidWebParser(), miwSettings.enforceHttps());
Map<String, Object> response = new TreeMap<>();
boolean valid;
VerifiableCredential verifiableCredential;
boolean dateValidation = true;

if (verificationRequest.containsKey(StringPool.VC_JWT_KEY)) {
JWTVerificationResult result = verifyVCAsJWT((String) verificationRequest.get(StringPool.VC_JWT_KEY), didResolver, withCredentialsValidation, withCredentialExpiryDate);
verifiableCredential = result.verifiableCredential;
valid = result.valid;
} else {

LinkedDataProofValidation proofValidation = LinkedDataProofValidation.newInstance(didResolver);
verifiableCredential = new VerifiableCredential(verificationRequest);
LinkedDataProofValidation proofValidation = LinkedDataProofValidation.newInstance(didResolver);

boolean valid = proofValidation.verify(verifiableCredential);

Map<String, Object> response = new TreeMap<>();
if (withCredentialsValidation) {
valid = proofValidation.verify(verifiableCredential);
} else {
valid = true;
}

//check expiry
boolean dateValidation = CommonService.validateExpiry(withCredentialExpiryDate, verifiableCredential, response);
dateValidation = CommonService.validateExpiry(withCredentialExpiryDate, verifiableCredential,
response);
}

response.put(StringPool.VALID, valid && dateValidation);
response.put("vc", verifiableCredential);
response.put(StringPool.VC, verificationRequest);

return response;
}
Original file line number Diff line number Diff line change
@@ -62,6 +62,7 @@
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.regex.Pattern;

@@ -193,7 +194,7 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl
x25519PrivateKey privateKey = walletKeyService.getPrivateKeyByWalletId(issuerWallet.getId());
// JWT Factory

SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, Date.from(vc.getExpirationDate()), vc,
SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, vc,
privateKey,
walletKeyService.getWalletKeyIdByWalletId(issuerWallet.getId()));

Loading