From 8dc5cd26a599a52ad7b43193f7d2e68dd999c340 Mon Sep 17 00:00:00 2001 From: balachandarg-tw <115633327+balachandarg-tw@users.noreply.github.com> Date: Fri, 22 Nov 2024 13:45:30 +0530 Subject: [PATCH] [INJIMBO-2324] Adding issuance date tolerance and logger update. (#58) * [INJIMOB-2311]: Update Issuance date validation with tolerance of 3sec. (#56) Signed-off-by: BalachandarG * [INJIMOB-2324]: Update org.sl4j Logger to java.util.logging Logger. (#57) * [INJIMOB-2324]: Update org.sl4j Logger to java.util.logging Logger. Signed-off-by: BalachandarG * [INJIMOB-2324]: Remove Local util Logger and directly using the log level methods available in java.util.logging. Signed-off-by: BalachandarG --------- Signed-off-by: BalachandarG --------- Signed-off-by: BalachandarG --- .../vercred/vcverifier/CredentialsVerifier.kt | 9 ++-- .../types/msomdoc/MsoMdocCredentialData.kt | 7 ++- .../msomdoc/MsoMdocVerifiableCredential.kt | 11 +++-- .../validator/MsoMdocValidator.kt | 11 +++-- .../verifier/LdpVerifier.kt | 11 +++-- .../verifier/MsoMdocVerifier.kt | 12 ++--- .../vercred/vcverifier/utils/DateUtils.kt | 22 +++++++--- .../vercred/vcverifier/utils/UtilsTest.kt | 44 ++++++++++++++++++- 8 files changed, 86 insertions(+), 41 deletions(-) diff --git a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt index 2c6651e..b11b09b 100644 --- a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt +++ b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt @@ -7,15 +7,12 @@ import io.mosip.vercred.vcverifier.constants.CredentialVerifierConstants.ERROR_C import io.mosip.vercred.vcverifier.constants.CredentialVerifierConstants.EXCEPTION_DURING_VERIFICATION import io.mosip.vercred.vcverifier.constants.CredentialVerifierConstants.ERROR_MESSAGE_VERIFICATION_FAILED import io.mosip.vercred.vcverifier.credentialverifier.CredentialVerifierFactory -import io.mosip.vercred.vcverifier.credentialverifier.verifier.LdpVerifier import io.mosip.vercred.vcverifier.data.VerificationResult -import org.slf4j.Logger -import org.slf4j.LoggerFactory +import java.util.logging.Logger class CredentialsVerifier { - private val Logger: Logger = LoggerFactory.getLogger(CredentialsVerifier::class.java.name) - + private val logger = Logger.getLogger(CredentialsVerifier::class.java.name) /** * @deprecated This method has been deprecated because it is not extensible for future use cases of supporting different VC format's verification @@ -25,7 +22,7 @@ class CredentialsVerifier { @Deprecated("This method has been deprecated because it is not extensible for future use cases of supporting different VC format's verification") fun verifyCredentials(credentials: String?): Boolean { if(credentials==null){ - Logger.error("Error - Input credential is null") + logger.severe("Error - Input credential is null") throw RuntimeException("Input credential is null") } val credentialVerifier = CredentialVerifierFactory().get(LDP_VC) diff --git a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocCredentialData.kt b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocCredentialData.kt index c04f112..92b68d9 100644 --- a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocCredentialData.kt +++ b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocCredentialData.kt @@ -9,14 +9,13 @@ import co.nstant.`in`.cbor.CborEncoder import co.nstant.`in`.cbor.model.* import co.nstant.`in`.cbor.model.Array import co.nstant.`in`.cbor.model.Map -import org.slf4j.LoggerFactory -import org.slf4j.Logger +import java.util.logging.Logger typealias IssuerAuth = Array? typealias IssuerSignedNamespaces = Map -private val Logger: Logger = LoggerFactory.getLogger("VC-Verifier") +private val logger = Logger.getLogger(MsoMdocCredentialData::class.java.name) fun IssuerSignedNamespaces.extractFieldValue(fieldToBeExtracted: String): String { @@ -45,7 +44,7 @@ fun IssuerSignedNamespaces.extractFieldValue(fieldToBeExtracted: String): String fun IssuerAuth.extractMso(): Map { if (this == null) { - Logger.error("IssuerAuth in credential is not available") + logger.severe("IssuerAuth in credential is not available") throw RuntimeException("Invalid Issuer Auth") } diff --git a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt index c584328..2751e99 100644 --- a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt +++ b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt @@ -1,7 +1,5 @@ package io.mosip.vercred.vcverifier.credentialverifier.types.msomdoc -import org.slf4j.Logger -import org.slf4j.LoggerFactory import co.nstant.`in`.cbor.CborDecoder import co.nstant.`in`.cbor.model.Array import co.nstant.`in`.cbor.model.DataItem @@ -17,10 +15,11 @@ import io.mosip.vercred.vcverifier.data.ValidationStatus import io.mosip.vercred.vcverifier.exception.ValidationException import io.mosip.vercred.vcverifier.utils.Encoder import java.io.ByteArrayInputStream +import java.util.logging.Logger class MsoMdocVerifiableCredential : VerifiableCredential { - private val tag: String = MsoMdocVerifiableCredential::class.java.name - private val Logger: Logger = LoggerFactory.getLogger(MsoMdocVerifiableCredential::class.java.name) + + private val logger = Logger.getLogger(MsoMdocVerifiableCredential::class.java.name) override fun validate(credential: String): ValidationStatus { @@ -48,7 +47,7 @@ class MsoMdocVerifiableCredential : VerifiableCredential { val decodedData: ByteArray = try { Encoder().decodeFromBase64UrlFormatEncoded(credential) } catch (exception: Exception) { - Logger.error("Error occurred while base64Url decoding the credential " + exception.message) + logger.severe("Error occurred while base64Url decoding the credential " + exception.message) throw RuntimeException("Error on decoding base64Url encoded data " + exception.message) } @@ -56,7 +55,7 @@ class MsoMdocVerifiableCredential : VerifiableCredential { try { cbors = CborDecoder(ByteArrayInputStream(decodedData)).decode() } catch (exception: Exception) { - Logger.error("Error occurred while CBOR decoding the credential " + exception.message) + logger.severe("Error occurred while CBOR decoding the credential " + exception.message) throw RuntimeException("Error on decoding CBOR encoded data " + exception.message) } diff --git a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/MsoMdocValidator.kt b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/MsoMdocValidator.kt index 6598952..7002df5 100644 --- a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/MsoMdocValidator.kt +++ b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/MsoMdocValidator.kt @@ -1,12 +1,9 @@ package io.mosip.vercred.vcverifier.credentialverifier.validator -import org.slf4j.Logger -import org.slf4j.LoggerFactory import co.nstant.`in`.cbor.model.DataItem import co.nstant.`in`.cbor.model.MajorType import co.nstant.`in`.cbor.model.Map import co.nstant.`in`.cbor.model.UnicodeString -import io.mosip.vercred.vcverifier.CredentialsVerifier import io.mosip.vercred.vcverifier.constants.CredentialValidatorConstants.ERROR_CODE_INVALID_DATE_MSO import io.mosip.vercred.vcverifier.constants.CredentialValidatorConstants.ERROR_MESSAGE_INVALID_DATE_MSO import io.mosip.vercred.vcverifier.credentialverifier.types.msomdoc.MsoMdocVerifiableCredential @@ -14,9 +11,11 @@ import io.mosip.vercred.vcverifier.credentialverifier.types.msomdoc.extractMso import io.mosip.vercred.vcverifier.exception.UnknownException import io.mosip.vercred.vcverifier.exception.ValidationException import io.mosip.vercred.vcverifier.utils.DateUtils +import java.util.logging.Logger class MsoMdocValidator { - private val Logger: Logger = LoggerFactory.getLogger(MsoMdocValidator::class.java.name) + private val logger = Logger.getLogger(MsoMdocValidator::class.java.name) + fun validate(credential: String): Boolean { @@ -31,7 +30,7 @@ class MsoMdocValidator { val validFrom: DataItem? = validityInfo["validFrom"] val validUntil: DataItem? = validityInfo["validUntil"] if (validUntil == null || validFrom == null) { - Logger.error("validUntil / validFrom is not available in the credential's MSO") + logger.severe("validUntil / validFrom is not available in the credential's MSO") throw ValidationException(ERROR_MESSAGE_INVALID_DATE_MSO, ERROR_CODE_INVALID_DATE_MSO) } val isCurrentTimeGreaterThanValidFrom = @@ -45,7 +44,7 @@ class MsoMdocValidator { ) ?: return false ) ?: false if (!(isCurrentTimeLessThanValidUntil && isCurrentTimeGreaterThanValidFrom && isValidUntilGreaterThanValidFrom)) { - Logger.error("Error while doing validity verification - invalid validUntil / validFrom in the MSO of the credential") + logger.severe("Error while doing validity verification - invalid validUntil / validFrom in the MSO of the credential") throw ValidationException(ERROR_MESSAGE_INVALID_DATE_MSO, ERROR_CODE_INVALID_DATE_MSO) } return true diff --git a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifier.kt b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifier.kt index ef27380..fdf5c12 100644 --- a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifier.kt +++ b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifier.kt @@ -33,8 +33,6 @@ import okhttp3.Request import org.bouncycastle.jce.provider.BouncyCastleProvider import org.bouncycastle.util.encoders.Hex import org.bouncycastle.util.io.pem.PemReader -import org.slf4j.Logger -import org.slf4j.LoggerFactory import java.io.StringReader import java.net.URI import java.security.KeyFactory @@ -43,11 +41,12 @@ import java.security.PublicKey import java.security.Security import java.security.cert.CertificateException import java.security.spec.X509EncodedKeySpec +import java.util.logging.Logger class LdpVerifier { - private val Logger: Logger = LoggerFactory.getLogger(LdpVerifier::class.java.name) + private val logger = Logger.getLogger(LdpVerifier::class.java.name) private var provider: BouncyCastleProvider = BouncyCastleProvider() private val SIGNATURE_VERIFIER: Map = mapOf( @@ -68,7 +67,7 @@ class LdpVerifier { fun verify(credential: String): Boolean { - Logger.info("Received Credentials Verification - Start") + logger.info("Received Credentials Verification - Start") val confDocumentLoader: ConfigurableDocumentLoader = getConfigurableDocumentLoader() val vcJsonLdObject: JsonLDObject = JsonLDObject.fromJson(credential) vcJsonLdObject.documentLoader = confDocumentLoader @@ -136,7 +135,7 @@ class LdpVerifier { throw PublicKeyNotFoundException("Public key object is null") } } catch (e: Exception) { - Logger.error("Error Generating public key object", e) + logger.severe("Error Generating public key object$e") throw PublicKeyNotFoundException("Public key object is null") } } @@ -165,7 +164,7 @@ class LdpVerifier { } throw PublicKeyNotFoundException("Public key object is null") } catch (e: Exception) { - Logger.error("Error generating public key object", e) + logger.severe("Error generating public key object $e") throw PublicKeyNotFoundException("Public key object is null") } } diff --git a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifier.kt b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifier.kt index 3de0cfd..d5dc143 100644 --- a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifier.kt +++ b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifier.kt @@ -1,7 +1,5 @@ package io.mosip.vercred.vcverifier.credentialverifier.verifier -import org.slf4j.Logger -import org.slf4j.LoggerFactory import co.nstant.`in`.cbor.CborDecoder import co.nstant.`in`.cbor.CborEncoder import co.nstant.`in`.cbor.model.Array @@ -26,6 +24,7 @@ import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.security.cert.CertificateFactory import java.security.cert.X509Certificate +import java.util.logging.Logger import java.util.regex.Matcher import java.util.regex.Pattern @@ -33,7 +32,8 @@ private const val ISSUING_COUNTRY = "issuing_country" class MsoMdocVerifier { - private val Logger: Logger = LoggerFactory.getLogger(MsoMdocVerifier::class.java.name) + private val logger = Logger.getLogger(MsoMdocVerifier::class.java.name) + private val util: io.mosip.vercred.vcverifier.utils.Util = @@ -108,11 +108,11 @@ class MsoMdocVerifier { private fun verifyDocType(mso: Map, docTypeInDocuments: DataItem?): Boolean { val docTypeInMso = mso["docType"] if (docTypeInDocuments == null) { - Logger.error("Error while doing docType property verification - docType property not found in the credential") + logger.severe("Error while doing docType property verification - docType property not found in the credential") throw InvalidPropertyException("Property docType not found in the credential") } if (docTypeInMso != docTypeInDocuments) { - Logger.error("Error while doing docType property verification - Property mismatch with docType in the credential") + logger.severe("Error while doing docType property verification - Property mismatch with docType in the credential") throw InvalidPropertyException("Property mismatch with docType in the credential") } return true @@ -191,7 +191,7 @@ class MsoMdocVerifier { for ((actualDigestId, actualDigest) in actualDigests) { if (!actualDigest.contentEquals(calculatedDigests[actualDigestId])) { - Logger.error("Error while doing valueDigests verification - mismatch in digests found") + logger.severe("Error while doing valueDigests verification - mismatch in digests found") throw LikelyTamperedException("valueDigests verification failed - mismatch in digests with $actualDigestId") } } diff --git a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/DateUtils.kt b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/DateUtils.kt index 51982b7..33c5992 100644 --- a/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/DateUtils.kt +++ b/vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/DateUtils.kt @@ -16,17 +16,16 @@ import io.mosip.vercred.vcverifier.constants.CredentialValidatorConstants.VALID_ import io.mosip.vercred.vcverifier.constants.CredentialValidatorConstants.VALID_UNTIL import io.mosip.vercred.vcverifier.exception.ValidationException import org.json.JSONObject -import org.slf4j.Logger -import org.slf4j.LoggerFactory import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date import java.util.Locale import java.util.TimeZone +import java.util.logging.Logger object DateUtils { - private val Logger: Logger = LoggerFactory.getLogger("VC-Verifier") + private val logger = Logger.getLogger(DateUtils::class.java.name) private val dateFormats = listOf( ("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"), @@ -43,14 +42,14 @@ object DateUtils { return try { val inputDate: Date? = parseDate(inputDateString) if (inputDate == null) { - Logger.error("Given date is not available in supported date formats") + logger.severe("Given date is not available in supported date formats") return false } val currentDate = Calendar.getInstance(TimeZone.getTimeZone(UTC)).time inputDate.before(currentDate) } catch (e: Exception) { - Logger.error("Error while comparing dates ${e.message}") + logger.severe("Error while comparing dates ${e.message}") false } } @@ -79,7 +78,10 @@ object DateUtils { } - if (!isDatePassedCurrentDate(vcJsonObject.optString(ISSUANCE_DATE))) { + val issuanceDate: Date = parseDate(vcJsonObject.optString(ISSUANCE_DATE)) + ?: throw ValidationException(ERROR_ISSUANCE_DATE_INVALID, "${ERROR_CODE_INVALID}${ISSUANCE_DATE}") + + if (issuanceDate.isFutureDateWithTolerance()) { throw ValidationException(ERROR_CURRENT_DATE_BEFORE_ISSUANCE_DATE, ERROR_CODE_CURRENT_DATE_BEFORE_ISSUANCE_DATE ) @@ -112,4 +114,12 @@ object DateUtils { return inputDate.isNotEmpty() && isDatePassedCurrentDate(inputDate) } +} + +fun Date.isFutureDateWithTolerance(toleranceInMilliSeconds: Long = 3000): Boolean { + val currentTime = System.currentTimeMillis() + val inputDateTime = this.time + + val upperBound = currentTime + toleranceInMilliSeconds + return inputDateTime > upperBound } \ No newline at end of file diff --git a/vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/UtilsTest.kt b/vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/UtilsTest.kt index 7d1a058..127d5bb 100644 --- a/vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/UtilsTest.kt +++ b/vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/UtilsTest.kt @@ -8,10 +8,10 @@ import org.junit.jupiter.api.Assertions.assertArrayEquals import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import java.io.ByteArrayOutputStream import java.util.Calendar +import java.util.Date class UtilsTest { @@ -133,4 +133,46 @@ class UtilsTest { ), (digest) ) } + + @Test + fun `test when issuanceDate time is not future date and 10 seconds less than currentDate time `() { + val currentDate = Date() + val issuanceDate = Date(currentDate.time-10000) + val result = issuanceDate.isFutureDateWithTolerance() + assertFalse(result) + } + + @Test + fun `test when issuanceDate time is not future date and 3 seconds less than currentDate time `() { + val currentDate = Date() + val issuanceDate = Date(currentDate.time-3000) + val result = issuanceDate.isFutureDateWithTolerance() + assertFalse(result) + } + + @Test + fun `test when issuanceDate time equal to future date time`() { + val issuanceDate = Date() + val result = issuanceDate.isFutureDateWithTolerance() + assertFalse(result) + } + + + @Test + fun `test when issuanceDate time is future date time but within tolerance range`() { + val currentDate = Date() + val issuanceDate = Date(currentDate.time+3000) + + val result = issuanceDate.isFutureDateWithTolerance() + assertFalse(result) + } + + @Test + fun `test when issuanceDate time is future date time but outside tolerance range`() { + val currentDate = Date() + val issuanceDate = Date(currentDate.time+5000) + + val result = issuanceDate.isFutureDateWithTolerance() + assertTrue(result) + } } \ No newline at end of file