diff --git a/.github/workflows/push_trigger.yml b/.github/workflows/push_trigger.yml index 29f5d376..f0d1bf47 100644 --- a/.github/workflows/push_trigger.yml +++ b/.github/workflows/push_trigger.yml @@ -110,7 +110,7 @@ jobs: - name: Publish the maven package run: | - mvn deploy -DaltDeploymentRepository=ossrh::default::${{ secrets.OSSRH_SNAPSHOT_URL }} -s $GITHUB_WORKSPACE/settings.xml -f pom.xml + mvn deploy -DaltDeploymentRepository=ossrh::default::${{ secrets.RELEASE_URL }} -s $GITHUB_WORKSPACE/settings.xml -f pom.xml env: GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} GPG_TTY: $(tty) diff --git a/.github/workflows/release_changes.yml b/.github/workflows/release_changes.yml index cc9c2956..5d8e1a32 100644 --- a/.github/workflows/release_changes.yml +++ b/.github/workflows/release_changes.yml @@ -27,6 +27,11 @@ jobs: echo "BRANCH_NAME=$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" >> $GITHUB_ENV echo "GPG_TTY=$(tty)" >> $GITHUB_ENV + - name: update Branch name in badges + run: | + sed -i 's/branch=.*)]/branch=${{ env.BRANCH_NAME }}\)]/g' README.md + sed -i 's/branch=.*\&/branch=${{ env.BRANCH_NAME }}\&/g' README.md + - name: Mannualy changing the pom versions run: find . -type f -name "*pom.xml" -print0 | xargs -0 sed -i "s/${{ github.event.inputs.snapshotTags }}/${{ github.event.inputs.releaseTags }}/g" @@ -48,7 +53,7 @@ jobs: uses: peter-evans/create-pull-request@v3 with: token: ${{ secrets.ACTION_PAT }} - commit-message: Updated Pom versions for release changes + commit-message: Release Bot Pre-release changes title: Release changes body: Automated PR for ${{ github.event.inputs.releaseTags }} release. branch: release-branch diff --git a/.github/workflows/tag.yaml b/.github/workflows/tag.yaml new file mode 100644 index 00000000..e9bba0e6 --- /dev/null +++ b/.github/workflows/tag.yaml @@ -0,0 +1,43 @@ +name: Tagging of repos + +env: + tag: v1.2.3 + +on: + workflow_dispatch: + inputs: + tag: + description: 'Tag to be published' + required: true + default: 'v1.2.3' + type: string + body: + description: 'Release body message' + required: true + default: 'Changes in this Release' + type: string + pre-release: + description: 'Pre-release? True/False' + required: true + default: False + type: string + +jobs: + build: + name: Create Release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: ${{ github.event.inputs.tag }} + release_name: ${{ github.event.inputs.tag }} + body: | + ${{ github.event.inputs.body }} + draft: false + prerelease: ${{fromJSON(github.event.inputs.pre-release)}} diff --git a/README.md b/README.md index 836d8bde..c0e31682 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![Maven Package upon a push](https://github.com/mosip/print/actions/workflows/push_trigger.yml/badge.svg?branch=release-1.2.0)](https://github.com/mosip/print/actions/workflows/push_trigger.yml) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?branch=release-1.2.0&project=mosip_admin-services&id=mosip_admin-services&metric=alert_status)](https://sonarcloud.io/dashboard?branch=release-1.2.0&id=mosip_admin-services) +[![Maven Package upon a push](https://github.com/mosip/print/actions/workflows/push_trigger.yml/badge.svg?branch=release-1.2.0.1)](https://github.com/mosip/print/actions/workflows/push_trigger.yml) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?branch=release-1.2.0.1&project=mosip_admin-services&id=mosip_admin-services&metric=alert_status)](https://sonarcloud.io/dashboard?branch=release-1.2.0.1&id=mosip_admin-services) # Print Service ## Overview diff --git a/pom.xml b/pom.xml index 46c58152..c85f8dc5 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ io.mosip.print print - 1.2.0.1-SNAPSHOT + 1.2.0.1-B1 print @@ -39,7 +39,7 @@ **/dto/**,**/config/**,**/api/** 1.4.2 2.8.4 - 1.2.0.1-SNAPSHOT + 1.2.0.1-B1 7.1.0 2.0.0 5.5.13 @@ -103,7 +103,7 @@ org.json json - 20190722 + 20230227 org.slf4j @@ -230,9 +230,9 @@ 2.12.0 - info.weboftrust - ld-signatures-java - 0.8.0 + io.mosip.vercred + vcverifier + 1.0-SNAPSHOT diff --git a/src/main/java/io/mosip/print/PrintPDFApplication.java b/src/main/java/io/mosip/print/PrintPDFApplication.java index 31f72703..0465f1c9 100644 --- a/src/main/java/io/mosip/print/PrintPDFApplication.java +++ b/src/main/java/io/mosip/print/PrintPDFApplication.java @@ -1,5 +1,6 @@ package io.mosip.print; +import io.mosip.vercred.CredentialsVerifier; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; @@ -29,6 +30,11 @@ public CbeffUtil getCbeffUtil() { return new CbeffImpl(); } + @Bean + public CredentialsVerifier credentialsVerifier() { + return new CredentialsVerifier(); + } + @Bean public ThreadPoolTaskScheduler taskScheduler() { ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); diff --git a/src/main/java/io/mosip/print/service/impl/PrintServiceImpl.java b/src/main/java/io/mosip/print/service/impl/PrintServiceImpl.java index d8ea0a49..07f20696 100644 --- a/src/main/java/io/mosip/print/service/impl/PrintServiceImpl.java +++ b/src/main/java/io/mosip/print/service/impl/PrintServiceImpl.java @@ -31,6 +31,12 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import io.mosip.print.exception.*; +import io.mosip.vercred.CredentialsVerifier; +import io.mosip.vercred.exception.ProofDocumentNotFoundException; +import io.mosip.vercred.exception.ProofTypeNotFoundException; +import io.mosip.vercred.exception.PubicKeyNotFoundException; +import io.mosip.vercred.exception.UnknownException; import org.apache.commons.codec.binary.Base64; import org.joda.time.DateTime; import org.json.simple.JSONArray; @@ -56,20 +62,6 @@ import io.mosip.print.dto.CryptoWithPinResponseDto; import io.mosip.print.dto.DataShare; import io.mosip.print.dto.JsonValue; -import io.mosip.print.exception.ApiNotAccessibleException; -import io.mosip.print.exception.ApisResourceAccessException; -import io.mosip.print.exception.CryptoManagerException; -import io.mosip.print.exception.DataShareException; -import io.mosip.print.exception.ExceptionUtils; -import io.mosip.print.exception.IdRepoAppException; -import io.mosip.print.exception.IdentityNotFoundException; -import io.mosip.print.exception.PDFGeneratorException; -import io.mosip.print.exception.PDFSignatureException; -import io.mosip.print.exception.ParsingException; -import io.mosip.print.exception.PlatformErrorMessages; -import io.mosip.print.exception.QrcodeGenerationException; -import io.mosip.print.exception.TemplateProcessingFailureException; -import io.mosip.print.exception.UINNotFoundInDatabase; import io.mosip.print.logger.LogDescription; import io.mosip.print.logger.PrintLogger; import io.mosip.print.model.CredentialStatusEvent; @@ -81,7 +73,6 @@ import io.mosip.print.spi.QrCodeGenerator; import io.mosip.print.util.AuditLogRequestBuilder; import io.mosip.print.util.CbeffToBiometricUtil; -import io.mosip.print.util.CredentialsVerifier; import io.mosip.print.util.CryptoCoreUtil; import io.mosip.print.util.CryptoUtil; import io.mosip.print.util.DataShareUtil; @@ -201,6 +192,7 @@ public class PrintServiceImpl implements PrintService{ public boolean generateCard(EventModel eventModel) { String credential = null; boolean isPrinted = false; + boolean verified=false; try { if (eventModel.getEvent().getDataShareUri() == null || eventModel.getEvent().getDataShareUri().isEmpty()) { credential = eventModel.getEvent().getData().get("credential").toString(); @@ -211,12 +203,22 @@ public boolean generateCard(EventModel eventModel) { } String ecryptionPin = eventModel.getEvent().getData().get("protectionKey").toString(); String decodedCredential = cryptoCoreUtil.decrypt(credential); + printLogger.debug("vc is printed security valuation.... : {}",decodedCredential); if (verifyCredentialsFlag){ printLogger.info("Configured received credentials to be verified. Flag {}", verifyCredentialsFlag); - boolean verified = credentialsVerifier.verifyCredentials(decodedCredential); - if (!verified) { + try { + verified=credentialsVerifier.verifyPrintCredentials(decodedCredential); + if (!verified) { + printLogger.error("Received Credentials failed in verifiable credential verify method. So, the credentials will not be printed." + + " Id: {}, Transaction Id: {}", eventModel.getEvent().getId(), eventModel.getEvent().getTransactionId()); + return false; + } + }catch (ProofDocumentNotFoundException | ProofTypeNotFoundException e){ + printLogger.error("Proof document is not available in the received credentials." + + " Id: {}, Transaction Id: {}", eventModel.getEvent().getId(), eventModel.getEvent().getTransactionId()); + }catch (UnknownException | PubicKeyNotFoundException e){ printLogger.error("Received Credentials failed in verifiable credential verify method. So, the credentials will not be printed." + - " Id: {}, Transaction Id: {}", eventModel.getEvent().getId(), eventModel.getEvent().getTransactionId()); + " Id: {}, Transaction Id: {}", eventModel.getEvent().getId(), eventModel.getEvent().getTransactionId()); return false; } } diff --git a/src/main/java/io/mosip/print/util/CredentialsVerifier.java b/src/main/java/io/mosip/print/util/CredentialsVerifier.java deleted file mode 100644 index 706f78f9..00000000 --- a/src/main/java/io/mosip/print/util/CredentialsVerifier.java +++ /dev/null @@ -1,147 +0,0 @@ -package io.mosip.print.util; - -import java.io.IOException; -import java.io.StringReader; -import java.net.URI; -import java.security.GeneralSecurityException; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.Signature; -import java.security.SignatureException; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.MGF1ParameterSpec; -import java.security.spec.PSSParameterSpec; -import java.security.spec.X509EncodedKeySpec; -import java.text.ParseException; -import java.util.Objects; - -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.nimbusds.jose.JWSObject; - -import org.bouncycastle.util.io.pem.PemObject; -import org.bouncycastle.util.io.pem.PemReader; -import org.slf4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpMethod; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -import foundation.identity.jsonld.ConfigurableDocumentLoader; -import foundation.identity.jsonld.JsonLDException; -import foundation.identity.jsonld.JsonLDObject; -import info.weboftrust.ldsignatures.LdProof; -import info.weboftrust.ldsignatures.canonicalizer.URDNA2015Canonicalizer; -import info.weboftrust.ldsignatures.util.JWSUtil; -import io.mosip.print.constant.CredentialVerifierConstants; -import io.mosip.print.logger.PrintLogger; - -@Component -public class CredentialsVerifier { - - Logger CredVerifierLogger = PrintLogger.getLogger(CredentialsVerifier.class); - - @Autowired - private RestTemplate restTemplate; - - public boolean verifyCredentials(String credentials){ - CredVerifierLogger.info("Received Credentials Verification - Start."); - ConfigurableDocumentLoader confDocumentLoader = new ConfigurableDocumentLoader(); - confDocumentLoader.setEnableHttps(true); - confDocumentLoader.setEnableHttp(true); - confDocumentLoader.setEnableFile(false); - - JsonLDObject vcJsonLdObject = JsonLDObject.fromJson(credentials); - vcJsonLdObject.setDocumentLoader(confDocumentLoader); - - LdProof ldProofWithJWS = LdProof.getFromJsonLDObject(vcJsonLdObject); - if (Objects.isNull(ldProofWithJWS)) { - CredVerifierLogger.error("Proof document is not available in the received credentials."); - return false; - } - - String ldProofTerm = ldProofWithJWS.getType(); - if (!CredentialVerifierConstants.SIGNATURE_SUITE_TERM.equals(ldProofTerm)) { - CredVerifierLogger.error("Proof Type available in received credentials is not matching " + - " with supported proof terms. Recevied Type: {}", ldProofTerm); - return false; - } - - try { - - URDNA2015Canonicalizer canonicalizer = new URDNA2015Canonicalizer(); - byte[] canonicalHashBytes = canonicalizer.canonicalize(ldProofWithJWS, vcJsonLdObject); - CredVerifierLogger.info("Completed Canonicalization for the received credentials."); - String signJWS = ldProofWithJWS.getJws(); - JWSObject jwsObject = JWSObject.parse(signJWS); - byte[] vcSignBytes = jwsObject.getSignature().decode(); - URI publicKeyJsonUri = ldProofWithJWS.getVerificationMethod(); - PublicKey publicKeyObj = getPublicKeyFromVerificationMethod(publicKeyJsonUri); - if (Objects.isNull(publicKeyObj)) { - CredVerifierLogger.error("Public key object is null, returning false."); - return false; - } - CredVerifierLogger.info("Completed downloading public key from the issuer domain and constructed public key object."); - byte[] actualData = JWSUtil.getJwsSigningInput(jwsObject.getHeader(), canonicalHashBytes); - String jwsHeader = jwsObject.getHeader().getAlgorithm().getName(); - CredVerifierLogger.info("Performing signature verification after downloading the public key."); - return verifyCredentialSignature(jwsHeader, publicKeyObj, actualData, vcSignBytes); - } catch (IOException | GeneralSecurityException | JsonLDException | ParseException e) { - CredVerifierLogger.error("Error in doing verifiable credential verification process.", e); - } - return false; - } - - - private PublicKey getPublicKeyFromVerificationMethod(URI publicKeyJsonUri){ - - try { - ObjectNode response = restTemplate.exchange(publicKeyJsonUri, HttpMethod.GET, null, ObjectNode.class).getBody(); - String publicKeyPem = response.get(CredentialVerifierConstants.PUBLIC_KEY_PEM).asText(); - CredVerifierLogger.info("public key download completed."); - StringReader strReader = new StringReader(publicKeyPem); - PemReader pemReader = new PemReader(strReader); - PemObject pemObject = pemReader.readPemObject(); - byte[] pubKeyBytes = pemObject.getContent(); - X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubKeyBytes); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - return keyFactory.generatePublic(pubKeySpec); - } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) { - CredVerifierLogger.error("Error Generating public key object.", e); - } - return null; - } - - private boolean verifyCredentialSignature(String algorithm, PublicKey publicKey, byte[] actualData, byte[] signature) { - - if (algorithm.equals(CredentialVerifierConstants.JWS_RS256_SIGN_ALGO_CONST)) { - try { - CredVerifierLogger.info("Validating signature using RS256 algorithm."); - Signature rsSignature = Signature.getInstance(CredentialVerifierConstants.RS256_ALGORITHM); - rsSignature.initVerify(publicKey); - rsSignature.update(actualData); - return rsSignature.verify(signature); - } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { - CredVerifierLogger.error("Error in Verifying credentials(RS256).", e); - } - } - try { - CredVerifierLogger.info("Validating signature using PS256 algorithm."); - Signature psSignature = Signature.getInstance(CredentialVerifierConstants.PS256_ALGORITHM); - - PSSParameterSpec pssParamSpec = new PSSParameterSpec(CredentialVerifierConstants.PSS_PARAM_SHA_256, CredentialVerifierConstants.PSS_PARAM_MGF1, - MGF1ParameterSpec.SHA256, CredentialVerifierConstants.PSS_PARAM_SALT_LEN, CredentialVerifierConstants.PSS_PARAM_TF); - psSignature.setParameter(pssParamSpec); - - psSignature.initVerify(publicKey); - psSignature.update(actualData); - return psSignature.verify(signature); - } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidAlgorithmParameterException e) { - CredVerifierLogger.error("Error in Verifying credentials(PS256).", e); - } - return false; - } - -}