Skip to content

Conversation

@swatigoel
Copy link
Contributor

@swatigoel swatigoel commented Nov 20, 2025

Summary by CodeRabbit

  • New Features

    • Credential status checks with per-credential results; presentation verification API and combined verify+status flows; expanded key resolution and new signature algorithm support (EdDSA, ES256K, RSA/JWK, DID/HTTP).
  • Bug Fixes

    • More robust date parsing, Base64 handling, JWT verification, and status-list decoding/validation.
  • Documentation

    • Reworked Kotlin verifier docs; added SD‑JWT draft and detailed verification guidance.
  • Tests

    • Expanded unit tests and fixtures for verification and status scenarios.
  • Chores

    • Sample app, build and publish metadata updates.

✏️ Tip: You can customize this high-level summary in your review settings.

@swatigoel swatigoel marked this pull request as draft November 20, 2025 08:11
@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

Walkthrough

Replaces Boolean revocation checks with a credential-status architecture, adds LdpStatusChecker/StatusCheckException and constants, updates key resolution (PublicKeyResolverFactory) and signature handling (SignatureFactory), modernizes utilities (date/base64/verifyJwt), expands public APIs to return status-aware results for credentials and presentations, adds Java sample app, and extends tests and JSON‑LD fixtures.

Changes

Cohort / File(s) Summary
Documentation
README.md, doc/sdjwt-kbjwt-verification-support.md, vc-verifier/kotlin/README.md
Adds SD‑JWT KB‑JWT verification doc, documents status checks, keyResolver, PresentationVerifier APIs, supported formats and updated API surface.
Build & Dependencies
vc-verifier/kotlin/gradle/libs.versions.toml, vc-verifier/kotlin/vcverifier/build.gradle.kts, vc-verifier/kotlin/vcverifier/publish-artifact.gradle, vc-verifier/kotlin/sample-java-app/pom.xml
Adds threetenbp dependency, Gradle task metadata, updates publication versions to 1.6.0, and adds a Maven POM for a sample Java app.
Samples & Examples
vc-verifier/kotlin/example/.../MainActivity.kt, vc-verifier/kotlin/sample-java-app/src/main/java/io/mosip/Main.java, vc-verifier/kotlin/sample-java-app/src/main/java/io/mosip/SampleConstants.java
Adds Java sample entrypoint and SAMPLE_FARMER_VC constant; example now verifies an explicit farmerVc JSON.
Core API: Credentials & Presentation
.../CredentialsVerifier.kt, .../PresentationVerifier.kt, .../data/Data.kt
Adds getCredentialStatus() and verifyAndGetCredentialStatus() APIs, introduces credential‑status data models (CredentialStatusResult, VCResultWithCredentialStatus, PresentationResultWithCredentialStatus, CredentialVerificationSummary), and uses a shared verifier factory instance.
Revocation → Status Refactor
.../credentialverifier/VerifiableCredential.kt, .../types/*, .../credentialverifier/types/*
Replaces isRevoked(...) Boolean API with checkStatus(...): Map<String,CredentialStatusResult> and updates implementations to delegate to new status checker.
Status Checker Implementation
vc-verifier/kotlin/vcverifier/src/main/java/.../statusChecker/LdpStatusChecker.kt, .../constants/StatusCheckerConstants.kt, .../exception/StatusCheckException.kt
Adds LdpStatusChecker for BitstringStatusList handling (fetch, verify, base64+gzip decode, bit extraction), constants and StatusCheckException with error codes.
Remove legacy revocation
.../revocation/LdpRevokeChecker.kt, .../revocation/MsoMdocRevokeChecker.kt, .../exception/RevocationCheckException.kt
Deletes legacy revocation checkers and RevocationCheckException.
Key Resolver & JWK Support
.../keyResolver/PublicKeyResolverFactory.kt, .../keyResolver/Utils.kt, .../keyResolver/types/did/DidJwkPublicKeyResolver.kt, .../keyResolver/types/did/DidWebPublicKeyResolver.kt, .../keyResolver/types/http/HttpsPublicKeyResolver.kt
Renames PublicKeyGetterFactory → PublicKeyResolverFactory; centralizes jwkToPublicKey with RSA/EC/OKP support and adjusts HTTP enum usage.
Signature Handling
.../signature/SignatureFactory.kt, .../verifier/LdpVerifier.kt, .../verifier/SdJwtVerifier.kt
Adds SignatureFactory to resolve verifiers (PS256/RS256/EdDSA/ES256K), replaces static maps, centralizes JWT verification calls and verification flow.
Network Manager enum rename
.../networkManager/NetworkManagerClient.kt
Renames HTTP_METHOD → HttpMethod and updates sendHTTPRequest signature and usages.
Utilities
.../utils/Base64Decoder.kt, .../utils/DateUtils.kt, .../utils/Util.kt, .../utils/ValidationHelper.kt, .../utils/LocalDocumentLoader.kt
Adds decodeFromBase64, migrates date parsing to three‑ten‑bp ISO parsing, adds formatEpochSecondsToIsoUtc, centralizes verifyJwt, switches JSONObject access to bracket style, and adds LocalDocumentLoader test utility.
Constants & Data Models
.../constants/CredentialValidatorConstants.kt, .../constants/CredentialVerifierConstants.kt, .../data/Data.kt
Removes DATE_REGEX, expands supported algorithms and key constants, adds credential-status related types and VerificationStatus.REVOKED, and renames DATA_MODEL → DataModel.
Validators & Minor Verifiers
.../validator/LdpValidator.kt, .../validator/SdJwtValidator.kt, .../verifier/MsoMdocVerifier.kt
Use DataModel enum, introduce SD‑JWT hash constants, and a small equality-check adjustment in MsoMdocVerifier.
Tests & Test Resources
vc-verifier/kotlin/vcverifier/src/test/... (many files)
Adds/updates extensive tests for status checking, SD‑JWT, key resolver, date utils; introduces many JSON‑LD contexts, VC/VP fixtures, SD‑JWT samples, and test utilities (readClasspathFile, mockHttpResponse).

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant CredentialsVerifier
    participant VerifierFactory
    participant VerifiableCredential
    participant LdpStatusChecker
    participant NetworkManager
    participant SignatureVerifier

    Caller->>CredentialsVerifier: verifyAndGetCredentialStatus(vc, format, purposes)
    CredentialsVerifier->>VerifierFactory: getVerifier(format)
    VerifierFactory-->>CredentialsVerifier: VerifiableCredential
    CredentialsVerifier->>VerifiableCredential: verify(vc)

    alt verification succeeds
        VerifiableCredential-->>CredentialsVerifier: VerificationResult(SUCCESS)
        CredentialsVerifier->>LdpStatusChecker: getStatuses(vc, purposes)
        LdpStatusChecker->>NetworkManager: HTTP GET statusListCredential
        NetworkManager-->>LdpStatusChecker: status-list VC
        LdpStatusChecker->>SignatureVerifier: verify(status-list VC)
        SignatureVerifier-->>LdpStatusChecker: valid / invalid
        alt signature valid
            LdpStatusChecker->>LdpStatusChecker: decode Base64 + GZIP, extract bit
            LdpStatusChecker-->>CredentialsVerifier: Map<purpose, CredentialStatusResult>
            CredentialsVerifier-->>Caller: CredentialVerificationSummary(success, statuses)
        else signature invalid / error
            LdpStatusChecker-->>CredentialsVerifier: StatusCheckException
            CredentialsVerifier-->>Caller: CredentialVerificationSummary(success, error-statuses)
        end
    else verification fails
        VerifiableCredential-->>CredentialsVerifier: VerificationResult(FAILED)
        CredentialsVerifier-->>Caller: CredentialVerificationSummary(failed, {})
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Files/areas needing extra attention:
    • LdpStatusChecker.kt — base64/gzip decoding, bit extraction, statusSize/statusMessage consistency and error mapping.
    • KeyResolver Utils & jwkToPublicKey — RSA/EC/OKP conversion correctness and exception mapping.
    • DateUtils.kt — ISO parsing, fractional‑second handling, and compatibility with fixtures.
    • CredentialsVerifier / PresentationVerifier API changes — backward compatibility and result shaping.
    • SignatureFactory mapping and SdJwtVerifier changes — algorithm mappings and centralized JWT verification.

Possibly related PRs

Suggested reviewers

  • swatigoel
  • abhip2565
  • mayuradesh

Poem

🐇 I hopped through code with tiny paws,
swapped revokes for statuses without a pause.
I fetched keys, unzipped base64 seas,
counted bits and handled time with ease.
Now verifications hop — hooray — applause!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.54% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title '[DRAFT PR] Critical code review' is vague and generic, using non-descriptive terms that fail to convey meaningful information about the changeset. Replace with a specific, concise title that summarizes the main changes, e.g., 'Add credential status verification and presentation verification APIs' or 'Refactor revocation checks to status-based verification system'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch release-1.6.x

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46ff55b and f3634ba.

📒 Files selected for processing (2)
  • vc-verifier/kotlin/sample-java-app/pom.xml (1 hunks)
  • vc-verifier/kotlin/vcverifier/publish-artifact.gradle (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • vc-verifier/kotlin/sample-java-app/pom.xml
  • vc-verifier/kotlin/vcverifier/publish-artifact.gradle
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (java-kotlin)
  • GitHub Check: build-maven-vc-verifier / maven-build
  • GitHub Check: Analyze (java-kotlin)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/CredentialValidatorConstants.kt (1)

102-107: Add ES256 to ALGORITHMS_SUPPORTED list.

The ALGORITHMS_SUPPORTED list omits ES256, which is fully supported throughout the codebase. Evidence shows JWS_ES256_SIGN_ALGO_CONST = "ES256" is defined, actively imported, and handled in signature verification (Util.kt, SignatureFactory.kt, keyResolver/Utils.kt). Additionally, consider adding the corresponding proof type (EcdsaSecp256r1Signature2019) to the PROOF_TYPES_SUPPORTED list for consistency, as it's currently also missing.

🧹 Nitpick comments (29)
vc-verifier/kotlin/vcverifier/build.gradle.kts (2)

118-119: Fix typo in jarRelease task description.

The description contains a spelling error: "Assemple" should be "Assemble".

   tasks.register<Jar>("jarRelease") {
     group = "release"
-    description = "Assemple Jar Release"
+    description = "Assemble Jar Release"

157-158: Fix typo in generatePom task description.

The description contains a spelling error: "Geneate" should be "Generate".

 tasks.register("generatePom") {
   group = "release"
-  description = "Geneate POM file for AAR and JAR Release"
+  description = "Generate POM file for AAR and JAR Release"
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/DateUtils.kt (1)

37-49: Consider logging the swallowed exception for debugging.

The outer catch block swallows the exception when OffsetDateTime.parse fails, which is intentional for the fallback mechanism. However, this can make debugging parsing issues difficult in production.

Consider logging the exception at debug level:

 fun parseDate(dateString: String): Date? {
     return try {
         val offsetDateTime = OffsetDateTime.parse(dateString, formatterWithOffset)
         Date(offsetDateTime.toInstant().toEpochMilli())
-    } catch (e: Exception) {
+    } catch (e: Exception) {
+        logger.fine("Failed to parse as offset date-time, trying local date-time: ${e.message}")
         try {
             val localDateTime = LocalDateTime.parse(dateString, formatterLocal)
             Date(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli())
         } catch (_: Exception) {
             null
         }
     }
 }
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/DateUtilsTest.kt (1)

1-134: Consider adding tests for the new formatEpochSecondsToIsoUtc method.

The test suite provides excellent coverage for parseDate and isValidDate. However, the new formatEpochSecondsToIsoUtc method (added in DateUtils.kt lines 115-118) is not tested here.

Consider adding test cases like:

@Test
fun testFormatEpochSecondsToIsoUtc() {
    val formatted = DateUtils.formatEpochSecondsToIsoUtc(1758104130L)
    assertEquals("2025-09-17T10:15:30Z", formatted)
}

@Test
fun testFormatEpochZero() {
    val formatted = DateUtils.formatEpochSecondsToIsoUtc(0L)
    assertEquals("1970-01-01T00:00:00Z", formatted)
}

@Test
fun testFormatNegativeEpoch() {
    val formatted = DateUtils.formatEpochSecondsToIsoUtc(-86400L)
    assertEquals("1969-12-31T00:00:00Z", formatted)
}
vc-verifier/kotlin/sample-java-app/src/main/java/io/mosip/Main.java (1)

12-13: Remove unnecessary blank lines.

These empty lines serve no purpose and reduce code readability.

     public static void main(String[] args) {
-
-
         System.out.println("Verifying VC from jar");
vc-verifier/kotlin/sample-java-app/pom.xml (2)

36-47: Remove duplicate Google Maven repository.

The Google Maven repository is declared twice with different IDs but the same URL. This is redundant and may cause confusion.

-        <repository>
-            <id>google-maven</id>
-            <url>https://maven.google.com/</url>
-        </repository>
         <repository>
             <id>danubetech-maven-public</id>
             <url>https://repo.danubetech.com/repository/maven-public/</url>
         </repository>
         <repository>
             <id>google</id>
             <url>https://maven.google.com</url>
         </repository>

51-55: Consider using a stable release version instead of SNAPSHOT.

Using a SNAPSHOT version (1.5.0-SNAPSHOT) in a sample application can lead to non-reproducible builds and unexpected behavior as SNAPSHOT artifacts can change without version updates. Consider using a stable release version once available to ensure consistent behavior for users trying the sample.

vc-verifier/kotlin/sample-java-app/src/main/java/io/mosip/SampleConstants.java (1)

11-26: Use obviously fake data in sample credentials.

The credential contains realistic-looking personal information (email: "ramesh@mosip.io", mobile: "9840298402"). For sample/demo code, it's better practice to use obviously fake data (e.g., "example@example.com", "555-0100") to avoid any potential PII concerns or confusion.

vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/mosipRevokedStatusList.json (1)

1-25: Consider adding newline at end of file.

The test resource file is missing a newline at the end, which is a common text file convention that helps with certain tools and version control systems.

vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/mosipUnrevokedVC.json (1)

1-94: Consider adding newline at end of file.

Similar to the other test resource files, this file is missing a newline at the end, which is a common text file convention.

vc-verifier/kotlin/README.md (1)

25-25: Align markdown headings with markdownlint hints

The bolded lines used as titles (**ldp_vc Error Codes**, ** mso_mdoc Format VC Error Codes **, ** vc+sd-jwt/dc+sd-jwt Format VC Error Codes **) and the ##### Verification Result on Success/Failure headings trigger markdownlint (MD036/MD037/MD001). Consider:

  • Turning these into proper headings, e.g. #### ldp_vc Error Codes, #### mso_mdoc Format VC Error Codes, #### vc+sd-jwt/dc+sd-jwt Format VC Error Codes.
  • Bumping the “Verification Result …” sections to #### so heading levels increase by one at a time.

This keeps docs consistent and silences the lints.

Also applies to: 69-69, 78-78, 126-126

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/data/Data.kt (2)

3-9: Avoid exposing StatusCheckException directly in CredentialStatusResult

CredentialStatusResult carries a StatusCheckException? field. Putting exception instances into a public data model:

  • Couples your API surface tightly to the exception type.
  • Risks leaking internal messages/stack details if this model is serialized or logged as‑is.
  • Makes it harder to evolve the exception hierarchy later.

Consider replacing error: StatusCheckException? with a lightweight structure (e.g. errorCode: StatusCheckErrorCode? plus optional errorMessage: String?), and keep the actual exception confined to logging.

Also applies to: 47-52


23-28: Document REVOKED as a possible VCResult.status value

VerificationStatus now includes REVOKED, but the README’s vcResults example still documents status: "valid|invalid|expired". For consistency with this enum and the new status‑list flow, consider updating the docs to mention revoked (or whatever external string you map it to) as an additional possible status.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt (1)

53-116: Document getStatuses() contract for null vs error results

getStatuses currently:

  • Returns null if credentialStatus is missing, or if no entries match statusPurposes.
  • Returns a list (possibly containing only failure entries) when entries exist but validation or downstream checks fail, with per‑purpose errors captured in CredentialStatusResult.error.

This is a reasonable contract, but it’s non‑obvious to callers. Consider tightening the KDoc to spell out these cases explicitly so integrators know when null means “no relevant status to check” vs when to inspect the returned list for failures.

vc-verifier/kotlin/vcverifier/src/test/resources/contexts/school-context.json (1)

1-19: Consider more precise schema.org mappings.

While this test context is functional, consider these refinements for better semantic accuracy:

  • Line 12: "amenities": "schema:benefits" → Consider "schema:amenityFeature" which is more semantically appropriate for school amenities
  • Lines 13, 15, 17: Fields mapped to generic "schema:Text" could use more specific schema.org terms if available
vc-verifier/kotlin/vcverifier/src/test/resources/contexts/farmer-context.json (2)

15-16: Duplicate schema.org mapping may cause ambiguity.

Both "district" and "villageOrTown" are mapped to "schema:addressLocality", which could lead to semantic confusion when processing this JSON-LD context. Consider using more specific or distinct schema.org terms to differentiate these geographic levels.


18-23: Consider more specific schema.org terms.

Several fields are mapped to generic "schema:Text" or "schema:Number". For better semantic precision in tests, consider using more specific schema.org terms where available (e.g., "schema:QuantitativeValue" for measurements, domain-specific properties for agriculture-related fields).

vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/mosipRevokedVC.json (1)

4-4: Consider using distinct values for UIN and VID.

Both UIN and VID are set to 123456. Using distinct values would improve test coverage and better represent real-world scenarios where these identifiers differ.

Also applies to: 21-21

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifier.kt (1)

46-46: Consider caching factory instances.

New factory instances are created on each verification call (PublicKeyResolverFactory() on line 46 and SignatureFactory() on line 53). If these factories are stateless, consider making them class-level constants or using a singleton pattern to avoid repeated instantiation overhead.

Example approach:

class LdpVerifier {
    private val logger = Logger.getLogger(LdpVerifier::class.java.name)
    private var provider: BouncyCastleProvider = BouncyCastleProvider()
    private val publicKeyResolverFactory = PublicKeyResolverFactory()
    private val signatureFactory = SignatureFactory()
    
    // ... rest of class
    
    fun verify(credential: String): Boolean {
        // ...
        val publicKeyObj = publicKeyResolverFactory.get(verificationMethod)
        // ...
        val signatureVerifier = signatureFactory.get(jwsObject.header.algorithm.name)
        // ...
    }
}

Also applies to: 53-53

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SdJwtValidator.kt (1)

358-386: Minor: Redundant null check.

Lines 374 and 383 use isNullOrBlank() on strings obtained via optString(), but optString() never returns null—it returns an empty string when the field is missing. Use isBlank() or isEmpty() instead for clarity.

Apply this diff:

-        if (alg.isNullOrBlank()) {
+        if (alg.isBlank()) {
             throw ValidationException( "Missing 'alg' in Key Binding JWT header","${ERROR_CODE_MISSING}KB_JWT_ALG")
         }
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt (1)

14-14: checkStatus no-op for MSO mdoc – document intent

checkStatus returning null means MSO mdoc credentials effectively bypass status checks, similar to the SdJwt behavior. That’s fine if MSO mdoc status is intentionally unsupported, but it would help future readers if this were documented (e.g., KDoc or a brief comment) and, if needed, statusPurposes was annotated/suppressed to avoid unused-parameter warnings.

You might also want to double‑check that CredentialsVerifier.verifyAndGetCredentialStatus consistently interprets null as “no status capability” rather than an error for this format. Based on learnings.

Also applies to: 47-49

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/CredentialsVerifierTest.kt (2)

3-18: Static mock of NetworkManagerClient is never reset

Both status‑list tests use mockkObject(NetworkManagerClient.Companion) and stub sendHTTPRequest, but there’s no corresponding teardown. Because this is a static/object mock, the stubbed behavior can bleed into other tests that happen to call NetworkManagerClient.sendHTTPRequest, causing subtle flakiness.

Consider adding an @AfterEach (or similar) that calls unmockkObject(NetworkManagerClient.Companion) or using MockK’s JUnit 5 extension plus clearAllMocks() to keep the mock scoped to each test run.

Also applies to: 179-225


152-166: Strengthen status-flow tests by asserting overall verificationResult semantics

The new tests nicely cover:

  • empty status list when verification fails, and
  • status entry contents for unrevoked vs revoked VCs.

Right now, the unrevoked/revoked tests only assert fields on CredentialStatusResult. To lock in the intended contract of CredentialVerificationSummary, consider also asserting the expected result.verificationResult.verificationStatus for both cases (e.g., whether a revoked status should flip the overall verification to false or remain true but with valid=false in the status entry).

That will make future changes to the verification/status aggregation behavior explicit and easier to reason about.

Also applies to: 188-202, 226-240

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt (2)

56-75: Check whether you want to preserve VC expiry information when signatures also fail

Right now, if validation marks the VC as expired you only surface ERR_VC_EXPIRED when verifySignatureStatus is true; if the signature fails you instead return a generic ERROR_CODE_VERIFICATION_FAILED, losing the expiry signal. If expiry should remain visible even when the signature is bad (e.g. to distinguish “expired” from “tampered”), consider prioritizing the expiry error code or encoding both in the result. Otherwise, this behavior is fine but should be intentional.


78-92: Clarify semantics of getCredentialStatus when checkStatus returns null

checkStatus can legitimately return null to indicate that status checks are not performed for a given format (e.g., SD‑JWT currently bypasses status checks). Mapping null to emptyList() makes callers unable to distinguish “status not supported” from “no status entries found”:

val credentialStatusArray =
    credentialVerifierFactory.get(credentialFormat)
        .checkStatus(credential, statusPurposeList)
return credentialStatusArray ?: emptyList()

If that distinction matters, you may want to propagate null (and reflect that in the API) or add a separate flag in CredentialVerificationSummary indicating whether status checking was actually attempted. Based on learnings

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidJwkPublicKeyResolverTest.kt (1)

114-138: RSA JWK resolution test looks good; minor naming nit

The RSA positive‑path test correctly verifies that an RSA JWK can be resolved and that the resulting public key has algorithm "RSA". That aligns well with the expanded key‑type support.

For clarity, consider renaming:

val unsupportedKeyTypeDid = "did:jwk:${encodeBase64Url(jwk)}"

to something like rsaDid or rsaJwkDid, since this test is specifically the supported RSA case.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (2)

34-55: Consider caching the default ConfigurableDocumentLoader in documentLoader

getConfigurableDocumentLoader currently builds a new loader whenever documentLoader is null:

fun getConfigurableDocumentLoader(): ConfigurableDocumentLoader {
    return documentLoader ?: run {
        val loader = ConfigurableDocumentLoader()
        loader.isEnableHttps = true
        loader.isEnableHttp = true
        loader.isEnableFile = false
        loader
    }
}

If the intent of the documentLoader field is to allow both test injection and reuse of a default loader, you can cache the created instance:

fun getConfigurableDocumentLoader(): ConfigurableDocumentLoader {
-    return documentLoader ?: run {
-        val loader = ConfigurableDocumentLoader()
-        loader.isEnableHttps = true
-        loader.isEnableHttp = true
-        loader.isEnableFile = false
-        loader
-    }
+    return documentLoader ?: run {
+        val loader = ConfigurableDocumentLoader().apply {
+            isEnableHttps = true
+            isEnableHttp = true
+            isEnableFile = false
+        }
+        documentLoader = loader
+        loader
+    }
}

This keeps the API flexible while avoiding repeated loader construction.


135-149: Preserve root cause when throwing SignatureVerificationException in verifyJwt

verifyJwt wraps any exception in a new SignatureVerificationException:

return try {
    signatureVerifier.verify(publicKey, signedData.toByteArray(UTF_8), signatureBytes)
} catch (e: Exception) {
    throw SignatureVerificationException("Signature verification failed: ${e.message}")
}

This normalizes errors but drops the original cause, which can be useful when debugging crypto or parsing issues. Consider chaining the cause:

- } catch (e: Exception) {
-     throw SignatureVerificationException("Signature verification failed: ${e.message}")
- }
+ } catch (e: Exception) {
+     throw SignatureVerificationException(
+         "Signature verification failed: ${e.message}",
+         e
+     )
+ }

(Adjust constructor signature if your exception type doesn’t yet accept a cause.)

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/StatusListRevocationCheckerTest.kt (1)

41-47: MockK setup is fine, but manual initialization is redundant

With @ExtendWith(MockKExtension::class) and @MockK fields, the extension already initializes mocks before each test. Calling MockKAnnotations.init(this) in setup() plus unmockkAll() in teardown() works but is more than you need. You can simplify to rely solely on the extension (and keep unmockkAll() if you prefer a hard reset):

@ExtendWith(MockKExtension::class)
class StatusListRevocationCheckerTest {

    @BeforeEach
    fun setup() {
        every { mockVerifierFactory.get(CredentialFormat.LDP_VC) } returns mockVerifier
        every { mockVerifier.verify(any()) } returns true
        checker = LdpStatusChecker(mockVerifierFactory)
    }
}

This reduces boilerplate without changing behavior.

Also applies to: 49-52

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac477ca and cf9aef3.

📒 Files selected for processing (70)
  • README.md (3 hunks)
  • doc/sdjwt-kbjwt-verification-support.md (1 hunks)
  • vc-verifier/kotlin/README.md (5 hunks)
  • vc-verifier/kotlin/example/src/main/java/io/mosip/vccred/example/MainActivity.kt (2 hunks)
  • vc-verifier/kotlin/gradle/libs.versions.toml (2 hunks)
  • vc-verifier/kotlin/sample-java-app/pom.xml (1 hunks)
  • vc-verifier/kotlin/sample-java-app/src/main/java/io/mosip/Main.java (1 hunks)
  • vc-verifier/kotlin/sample-java-app/src/main/java/io/mosip/SampleConstants.java (1 hunks)
  • vc-verifier/kotlin/vcverifier/build.gradle.kts (3 hunks)
  • vc-verifier/kotlin/vcverifier/publish-artifact.gradle (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/PresentationVerifier.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/CredentialValidatorConstants.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/CredentialVerifierConstants.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/StatusCheckerConstants.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/VerifiableCredential.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/revocation/LdpRevokeChecker.kt (0 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/revocation/MsoMdocRevokeChecker.kt (0 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/LdpVerifiableCredential.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt (3 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/LdpValidator.kt (3 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SdJwtValidator.kt (11 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifier.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifier.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/SdJwtVerifier.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/data/Data.kt (4 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/exception/RevocationCheckException.kt (0 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/exception/StatusCheckException.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/PublicKeyResolverFactory.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/Utils.kt (4 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidJwkPublicKeyResolver.kt (3 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidWebPublicKeyResolver.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/types/http/HttpsPublicKeyResolver.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/networkManager/NetworkManagerClient.kt (3 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/signature/SignatureFactory.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Base64Decoder.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/DateUtils.kt (4 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/LocalDocumentLoader.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (3 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/ValidationHelper.kt (5 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/CredentialsVerifierTest.kt (9 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/revocation/StatusListRevocationCheckerTest.kt (0 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/StatusListRevocationCheckerTest.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SDJwtValidatorTest.kt (19 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifierTest.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/keyResolver/PublicKeyResolverFactoryTest.kt (4 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/keyResolver/UtilsKtTest.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidJwkPublicKeyResolverTest.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidWebPublicKeyResolverTest.kt (5 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/DateUtilsTest.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/UtilsTest.kt (3 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/ed25519-2020-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/farmer-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/insurance-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/jws2020-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/mosip-ida-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/odrl-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/school-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/w3vc1-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/w3vc2-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/mosipRevokedStatusList.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/mosipRevokedVC.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/mosipUnrevokedStatusList.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/mosipUnrevokedVC.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/sd-jwt_vc/sdJwtWithKbJwtES256.txt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/sd-jwt_vc/sdJwtWithKbJwtEdDSA.txt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/sd-jwt_vc/sdJwtWithKbJwtEs256kAndCnfBeingJwk.txt (1 hunks)
💤 Files with no reviewable changes (4)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/revocation/LdpRevokeChecker.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/revocation/MsoMdocRevokeChecker.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/exception/RevocationCheckException.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/revocation/StatusListRevocationCheckerTest.kt
👮 Files not reviewed due to content moderation or server errors (1)
  • vc-verifier/kotlin/example/src/main/java/io/mosip/vccred/example/MainActivity.kt
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: abhip2565
Repo: mosip/vc-verifier PR: 202
File: vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt:18-21
Timestamp: 2025-11-03T12:07:06.442Z
Learning: For SD-JWT credentials in the vc-verifier project, the checkStatus method should return null to bypass status checks rather than throwing errors or implementing actual status verification.
📚 Learning: 2025-11-03T12:07:06.442Z
Learnt from: abhip2565
Repo: mosip/vc-verifier PR: 202
File: vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt:18-21
Timestamp: 2025-11-03T12:07:06.442Z
Learning: For SD-JWT credentials in the vc-verifier project, the checkStatus method should return null to bypass status checks rather than throwing errors or implementing actual status verification.

Applied to files:

  • vc-verifier/kotlin/README.md
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/SdJwtVerifier.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/StatusCheckerConstants.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/keyResolver/UtilsKtTest.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/exception/StatusCheckException.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SdJwtValidator.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/VerifiableCredential.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifierTest.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/LdpVerifiableCredential.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/UtilsTest.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/CredentialsVerifierTest.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/StatusListRevocationCheckerTest.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SDJwtValidatorTest.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt
🧬 Code graph analysis (11)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/DateUtilsTest.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/DateUtils.kt (2)
  • parseDate (37-49)
  • isValidDate (33-35)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidJwkPublicKeyResolver.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/Utils.kt (1)
  • jwkToPublicKey (214-225)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/SdJwtVerifier.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (1)
  • verifyJwt (135-149)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidWebPublicKeyResolver.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/networkManager/NetworkManagerClient.kt (2)
  • sendHTTPRequest (12-60)
  • sendHTTPRequest (14-58)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/keyResolver/UtilsKtTest.kt (2)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/Utils.kt (1)
  • jwkToPublicKey (214-225)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/testHelpers/TestAssertions.kt (1)
  • assertPublicKey (7-9)
vc-verifier/kotlin/sample-java-app/src/main/java/io/mosip/Main.java (2)
vc-verifier/kotlin/sample-java-app/src/main/java/io/mosip/SampleConstants.java (1)
  • SampleConstants (3-44)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (1)
  • getVerificationStatus (57-68)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SdJwtValidator.kt (2)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/DateUtils.kt (1)
  • formatEpochSecondsToIsoUtc (115-118)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/Utils.kt (1)
  • jwkToPublicKey (214-225)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/UtilsTest.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (1)
  • isValidHttpsUri (92-99)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (1)
  • isValidUri (79-90)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt (4)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/VerifiableCredential.kt (1)
  • verify (8-8)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifier.kt (1)
  • verify (32-76)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/SdJwtVerifier.kt (2)
  • verify (9-36)
  • verify (11-15)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifier.kt (1)
  • verify (41-72)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidJwkPublicKeyResolverTest.kt (1)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidKeyPublicKeyResolverTest.kt (1)
  • createParsedDid (78-83)
🪛 detekt (1.23.8)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SdJwtValidator.kt

[warning] 60-60: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/DateUtils.kt

[warning] 41-41: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt

[warning] 41-41: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)


[warning] 100-100: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

🪛 Gitleaks (8.29.0)
vc-verifier/kotlin/vcverifier/src/test/resources/sd-jwt_vc/sdJwtWithKbJwtEdDSA.txt

[high] 1-1: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

vc-verifier/kotlin/vcverifier/src/test/resources/sd-jwt_vc/sdJwtWithKbJwtEs256kAndCnfBeingJwk.txt

[high] 1-1: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SDJwtValidatorTest.kt

[high] 395-395: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)


[high] 550-550: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🪛 markdownlint-cli2 (0.18.1)
vc-verifier/kotlin/README.md

25-25: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


69-69: Spaces inside emphasis markers

(MD037, no-space-in-emphasis)


69-69: Spaces inside emphasis markers

(MD037, no-space-in-emphasis)


78-78: Spaces inside emphasis markers

(MD037, no-space-in-emphasis)


78-78: Spaces inside emphasis markers

(MD037, no-space-in-emphasis)


126-126: Heading levels should only increment by one level at a time
Expected: h4; Actual: h5

(MD001, heading-increment)

README.md

64-64: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)

doc/sdjwt-kbjwt-verification-support.md

27-27: Inconsistent indentation for list items at the same level
Expected: 3; Actual: 4

(MD005, list-indent)


34-34: Multiple spaces after hash on atx style heading

(MD019, no-multiple-space-atx)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (java-kotlin)

- digest length check based on hash algo `sha-256` - 32 bytes, `sha-384` to 48 bytes, `sha-512` to 64 bytes
- Fetch Holder's Public Key from SD JWT Payload
- `cnf` is mandatory. Must be present and value MUST be either `jwk` or `kid`
- Verify Signature
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix inconsistent list indentation.

The list item has 4 spaces of indentation instead of the expected 3, which is inconsistent with the other items at the same level.

Apply this diff:

-    - Verify Signature
+   - Verify Signature
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Verify Signature
- Verify Signature
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

27-27: Inconsistent indentation for list items at the same level
Expected: 3; Actual: 4

(MD005, list-indent)

🤖 Prompt for AI Agents
In doc/sdjwt-kbjwt-verification-support.md around line 27, the list item "Verify
Signature" is indented with 4 spaces instead of the expected 3; update that
line's leading spaces from 4 to 3 so its indentation matches the other sibling
list items at the same level.




### Sequence diagram - validate and verify `kb+jwt`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove extra space in heading.

The heading has multiple spaces between ### and the text. Markdown style guidelines recommend a single space.

Apply this diff:

-###  Sequence diagram - validate and verify `kb+jwt`
+### Sequence diagram - validate and verify `kb+jwt`
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

34-34: Multiple spaces after hash on atx style heading

(MD019, no-multiple-space-atx)

🤖 Prompt for AI Agents
In doc/sdjwt-kbjwt-verification-support.md around line 34, the markdown heading
contains multiple spaces between the '###' and the text; edit that line to use a
single space after '###' so it reads "### Sequence diagram - validate and verify
`kb+jwt`" (remove the extra space characters).

jsonldCommonJava = "1.8.0"
nimbusJoseJwt = "9.40"
springWeb = "5.0.20.RELEASE"
threetenbp = "1.7.0"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify threetenbp 1.7.0 compatibility and security.

The new threetenbp dependency aligns with the modernized date/time handling mentioned in the PR objectives. Ensure the chosen version 1.7.0 is stable, free from known vulnerabilities, and compatible with Android compileSdk=33 and Java 17 target.

Also applies to: 36-36


🌐 Web query:

Is threetenbp 1.7.0 compatible with Android SDK 33 and Java 17? Are there any known security issues?

💡 Result:

Short answer: Yes — threetenbp 1.7.0 runs on Java 17 and can be used in apps targeting Android API 33, but there are known security/fuzz issues in the v1.7.x line so you should upgrade to the latest 1.7.2.

Details & sources (short):

  • Compatibility: threetenbp is a pure‑Java backport that “runs on Java SE 6 (or later)” (so it runs on Java 17) and is distributed as a normal Maven artifact you can include in an Android build; Android itself includes java.time from API 26 onward but threetenbp can still be used where you prefer the backport/behavior. [1][2]
  • Security: OSS‑Fuzz / OSV records a security/fuzz finding that lists v1.7.0 (and v1.6.9/1.7.1) as affected (OSV-2024-171). Earlier CVE reports (CVE‑2024‑23081 / CVE‑2024‑23082) targeted older 1.6.8; Snyk/official site indicate newer 1.7.2 is the current non‑vulnerable release. Recommend updating to 1.7.2. [3][4][5]

If you want, I can:

  • point to the exact Maven coordinates and the upgrade change log, or
  • check your project (build.gradle / usage) and suggest whether you should use ThreeTenABP vs. the bundled java.time on Android.


Replace threetenbp 1.7.0 with 1.7.2 to address known security vulnerability.

threetenbp 1.7.0 is compatible with Java 17 and Android API 33, but contains a known security/fuzz vulnerability (OSV-2024-171). Upgrade to 1.7.2, the current non-vulnerable release.

Update gradle/libs.versions.toml line 11 and 36:

  • Line 11: threetenbp = "1.7.2"
  • Line 36: threetenbp = { module = "org.threeten:threetenbp", version.ref = "threetenbp" }
🤖 Prompt for AI Agents
In vc-verifier/kotlin/gradle/libs.versions.toml around lines 11 and 36, the
project pins threetenbp to 1.7.0 which has a known security vulnerability;
update line 11 to set threetenbp = "1.7.2" and update line 36 to use the shared
reference by setting threetenbp = { module = "org.threeten:threetenbp",
version.ref = "threetenbp" } so the dependency is upgraded to the non-vulnerable
1.7.2 and both declarations remain consistent.

Comment on lines 80 to 119
| Field | Error Code |
|---------------------------|------------------------------------|
| credential empty | ERR_EMPTY_VC |
| JWT | ERR_INVALID_JWT_FORMAT |
| alg in header | ERR_INVALID_ALG |
| typ in header | ERR_INVALID_TYP |
| vct in payload | ERR_INVALID_VCT |
| vct in payload | ERR_INVALID_VCT_URI |
| iss in payload | ERR_INVALID_ISS |
| _sd_alg in payload | ERR_INVALID_SD_ALG |
| iat in payload | ERR_ISSUANCE_DATE_IS_FUTURE_DATE |
| nbf in payload | ERR_PROCESSING_DATE_IS_FUTURE_DATE |
| exp in payload | ERR_VC_EXPIRED |
| aud in payload | ERR_INVALID_AUD |
| cnf in payload | ERR_INVALID_CNF |
| disclosure format | ERR_INVALID_DISCLOSURE_FORMAT |
| disclosure json length | ERR_INVALID_DISCLOSURE_STRUCTURE |
| disclosure claim | ERR_INVALID_DISCLOSURE_CLAIM_NAME |
| disclosure hash length | ERR_INVALID_ALG |
| disclosure digest empty | ERR_INVALID_DIGEST |
| KB JWT | ERR_INVALID_KB_JWT_FORMAT |
| KB JWT header | ERR_INVALID_KB_JWT_HEADER |
| KB JWT header | ERR_INVALID_KB_JWT_HEADER |
| alg in KB JWT header | ERR_MISSING_KB_JWT_ALG |
| alg in KB JWT header | ERR_INVALID_KB_JWT_ALG |
| typ in KB JWT header | ERR_INVALID_KB_JWT_TYP |
| cnf in KB JWT header | ERR_INVALID_CNF |
| cnf in KB JWT header | ERR_INVALID_CNF_TYPE |
| cnf in KB JWT header | ERR_INVALID_KB_SIGNATURE |
| aud in KB JWT payload | ERR_MISSING_AUD |
| nonce in KB JWT payload | ERR_MISSING_NONCE |
| sd_hash in KB JWT payload | ERR_MISSING_SD_HASH |
| iat in KB JWT payload | ERR_MISSING_IAT |
| aud in KB JWT payload | ERR_INVALID_AUD |
| nonce in KB JWT payload | ERR_INVALID_NONCE |
| iat in KB JWT payload | ERR_INVALID_KB_JWT_IAT |
| sd_hash in KB JWT payload | ERR_INVALID_SD_HASH |


For other unknown exceptions, error code will be `ERR_INVALID_UNKNOWN`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix duplicate KB JWT header row and confirm unknown-error code

In the vc+sd-jwt/dc+sd-jwt error table the KB JWT header row appears twice with the same error code (ERR_INVALID_KB_JWT_HEADER). That looks accidental; drop one row or clarify if a different condition/code was intended.

Also, this section uses ERR_INVALID_UNKNOWN as the catch‑all error, while other tables use ERR_GENERIC. Please confirm that this difference is intentional; if not, aligning on one generic code will avoid confusing consumers.

🤖 Prompt for AI Agents
In vc-verifier/kotlin/README.md around lines 80 to 119, the error table contains
a duplicated "KB JWT header" row with the same code and an inconsistent
catch-all code; remove the accidental duplicate "KB JWT header" row so only one
row for that condition remains (or, if the duplicate was meant to represent a
different condition, replace it with the correct condition and error code), and
standardize the final catch-all error code to match the rest of the docs
(replace ERR_INVALID_UNKNOWN with ERR_GENERIC unless the different code is
intentional—if intentional, add a short note explaining the divergence).

Comment on lines 56 to 75
<dependency>
<groupId>com.android.identity</groupId>
<artifactId>identity-credential</artifactId>
<version>20231002</version>
</dependency>
<dependency>
<groupId>info.weboftrust</groupId>
<artifactId>ld-signatures-java</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>decentralized-identity</groupId>
<artifactId>jsonld-common-java</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.8.20</version>
</dependency>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Verify and update outdated dependency versions.

Several dependencies appear to be quite old:

  • identity-credential:20231002 (from October 2023)
  • kotlin-stdlib:1.8.20 (from early 2023)

These versions are over 2 years old and may contain security vulnerabilities or lack important features. Verify if newer, more secure versions are available.


🌐 Web query:

What is the latest version of com.android.identity:identity-credential?

💡 Result:

The latest released version is 20231002. [1][2]

Sources:
[1] com.android.identity:identity-credential — Maven (mvnrepository).
[2] com.android.identity group listing — Maven (shows identity-credential latest).


🌐 Web query:

What is the latest stable version of Kotlin standard library (kotlin-stdlib)?

💡 Result:

The latest stable kotlin-stdlib is version 2.2.21 (released Oct 23, 2025). [1][2]

Sources:
[1] Kotlin releases (official) — releases list showing 2.2.21.
[2] Maven Central / Maven Repository — org.jetbrains.kotlin:kotlin-stdlib:2.2.21.


Update kotlin-stdlib to the latest stable version; verify other dependencies.

Verification shows identity-credential:20231002 is already at the latest available version and does not need updating.

However, kotlin-stdlib:1.8.20 is significantly outdated. The latest stable kotlin-stdlib is version 2.2.21 (released Oct 23, 2025). Update to 2.2.21.

Also verify the currency of ld-signatures-java:1.5.0 and jsonld-common-java:1.8.0, as their release dates and available updates remain unconfirmed.

🤖 Prompt for AI Agents
vc-verifier/kotlin/sample-java-app/pom.xml lines 56-75: the pom pins
kotlin-stdlib to 1.8.20 which must be bumped to the latest stable 2.2.21; edit
the dependency version for org.jetbrains.kotlin:kotlin-stdlib to 2.2.21, run a
full build and unit tests to catch any Kotlin 2.x compatibility issues, and
while here verify whether info.weboftrust:ld-signatures-java (1.5.0) and
decentralized-identity:jsonld-common-java (1.8.0) have newer releases — if
updates exist, bump them and re-run the build/tests as well.

Comment on lines 270 to 295
@Test
fun `should return error when statusSize is zero or negative`() {
val statusListJsonNegative = readFile("classpath:ldp_vc/status-list-vc.json")
.replace("\"encodedList\"", "\"statusSize\": -2, \"encodedList\"")
val statusListJsonZero = readFile("classpath:ldp_vc/status-list-vc.json")
.replace("\"encodedList\"", "\"statusSize\": 0, \"encodedList\"")
val (replacedVC, server) = prepareVC(
"classpath:ldp_vc/vcUnrevoked-https.json",
statusListJsonNegative
)
val (replacedVCZero, serverZero) = prepareVC(
"classpath:ldp_vc/vcUnrevoked-https.json",
statusListJsonZero
)

val resultNeg = checker.getStatuses(replacedVC)!!.first()

assertFalse(resultNeg.valid)
assertEquals(-1, resultNeg.status)
assertEquals(StatusCheckErrorCode.STATUS_VERIFICATION_ERROR, resultNeg.error?.errorCode)

val resultZero = checker.getStatuses(replacedVCZero)!!.first()

assertFalse(resultZero.valid)
assertEquals(-1, resultZero.status)
assertEquals(StatusCheckErrorCode.STATUS_VERIFICATION_ERROR, resultZero.error?.errorCode)

server.shutdown()
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Shut down both MockWebServer instances to avoid test resource leaks

In the statusSize is zero or negative test you start two servers but only shut down one:

val (replacedVC, server) = prepareVC(..., statusListJsonNegative)
val (replacedVCZero, serverZero) = prepareVC(..., statusListJsonZero)

// ...
val resultZero = checker.getStatuses(replacedVCZero)!!.first()

server.shutdown()   // serverZero is never shut down

This leaves serverZero running and can cause port/resource leaks in the test suite. Consider:

-        val (replacedVC, server) = prepareVC(
+        val (replacedVC, server) = prepareVC(
             "classpath:ldp_vc/vcUnrevoked-https.json",
             statusListJsonNegative
         )
-        val (replacedVCZero, serverZero) = prepareVC(
+        val (replacedVCZero, serverZero) = prepareVC(
             "classpath:ldp_vc/vcUnrevoked-https.json",
             statusListJsonZero
         )
@@
-        server.shutdown()
+        server.shutdown()
+        serverZero.shutdown()
🤖 Prompt for AI Agents
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/StatusListRevocationCheckerTest.kt
around lines 270-298: the test starts two MockWebServer instances (server and
serverZero) but only shuts down server, leaking serverZero; modify the test to
ensure both servers are shut down (e.g., call serverZero.shutdown() after
assertions), or better wrap server lifecycles in try/finally (or use JUnit
@AfterEach helper) so both server.shutdown() calls always run even if assertions
fail.

Comment on lines 19 to 27
@BeforeEach
fun setup() {
mockkObject(Util)
every { Util.verifyJwt(
any(),
any(),
any()
) } returns true
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Isolate MockK state for Util.verifyJwt to avoid cross‑test pollution

@BeforeEach globally mocks Util.verifyJwt:

@BeforeEach
fun setup() {
    mockkObject(Util)
    every { Util.verifyJwt(any(), any(), any()) } returns true
}

but there is no matching @AfterEach to unmock; only the should fail for invalid KB-JWT signature test calls unmockkAll() inline. This can:

  • Leave Util.verifyJwt mocked for other test classes that run after this one.
  • Make behavior depend on test execution order or parallelism.

Consider adding a dedicated teardown and using more targeted unmocking:

@AfterEach
fun tearDown() {
    unmockkAll() // or unmockkObject(Util) if you only mock Util here
}

and in the “invalid KB‑JWT signature” test, prefer unmockkObject(Util) over unmockkAll() so you don’t wipe unrelated mocks.

Also applies to: 401-444

🤖 Prompt for AI Agents
In
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SDJwtValidatorTest.kt
around lines 19 to 27, the setup mocks Util.verifyJwt in @BeforeEach but no
corresponding teardown, risking cross-test pollution; add an @AfterEach fun
tearDown() { unmockkObject(Util) } (or unmockkAll() if you truly need to clear
everything) to restore MockK state after each test, and replace any inline
unmockkAll() call in the “invalid KB-JWT signature” test with
unmockkObject(Util) to avoid wiping unrelated mocks.

Comment on lines 395 to 399
val vc = "eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJ2YytzZC1qd3QifQ.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlLmNvbSIsInZjdCI6InVybjpldWRpOnBpZDpkZToxIiwiaWF0IjoxNzU5ODk2MTU1LCJleHAiOjI1NDE3Mjk0MTAwMCwic3ViIjoidXNlcjEyMyIsIl9zZCI6WyJxLXhNRDBIbjFaVC1yc19UMmQyRXVHazNPVGluMUNqWVBrTU9JZDdBcFdVIiwibE9GU1hfZmtvYm9abWtCUDN4Vnl4d1ctZFNXV0did0pIX3FiTzRFdnBqMCIsIm9YWUNXRE85dEFhZWMxTDBpdXZVUlllVkFya1pmWGxXb0NIN3I4YWVDVUEiXSwiY25mIjp7ImtpZCI6Imh0dHBzOi8vaG9sZGVyLmV4YW1wbGUuY29tL2tleXMvMSJ9LCJfc2RfYWxnIjoic2hhLTI1NiJ9.MEQCIGi0VpKNYtj_ODtesOCVvvqJ2cUNHBRCLO4Luo0EDRjdAiBX2_PubKDMrZT0pAMdM5l8JtEJJ7QQW8soFI6quap2vA~WyJ6MjJaT05WUzREdkotd1pFbHJ6VEJnIiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~WyIyeXRpSDdXa2ZjTk0zRXBfN1IzblpBIiwiZmFtaWx5X25hbWUiLCJEb2UiXQ~WyIwbS1fY3J2QVc2YUdfbGM2enAtTXdBIiwiZW1haWwiLCJqb2huLmRvZUBleGFtcGxlLmNvbSJd~eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJrYitqd3QifQ.eyJpYXQiOjE3NTk4OTYxNTUsImF1ZCI6Imh0dHBzOi8vdmVyaWZpZXIuZXhhbXBsZS5jb20iLCJub25jZSI6InJhbmRvbS1ub25jZS1HSXRpNmRSTElITmlGR0dQcmdjQTJBIiwic2RfaGFzaCI6IlZoR1k0MTFycVE4dW12ZHRfc2tuSjdaVWhaQU5UYW44QS01aEFPWm5OeUUifQ.MEUCIBjYtbtg2-joD4krmgavj6AjXQwgWmxPKelUXgn_M3hRAiEA23hIj4m8SAZG-dJstoJsHomIG0Qw0QnflRCWVQVcaho"
val status = validator.validate(vc)
assertEquals("Unsupported 'kid' format in 'cnf'. Only DID format is supported", status.validationMessage)
assertEquals("ERR_INVALID_CNF_KID",status.validationErrorCode)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inline JWT fixtures are fine but will keep triggering secret scanners

The hard‑coded JWT‑looking strings in these tests are clearly fixtures, but tools like gitleaks flag them as potential secrets. To reduce noise in CI while keeping the coverage, you could:

  • Move the full JWTs into dedicated resource files (similar to other sd‑jwt fixtures) and reference them via ResourceUtils.getFile, or
  • Truncate or slightly mangle the payload/signature so they no longer parse as real JWTs, if that doesn’t affect validation logic.

This is optional, but it will make security scanning output cleaner.

Also applies to: 550-556

🧰 Tools
🪛 Gitleaks (8.29.0)

[high] 395-395: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.

(jwt)

🤖 Prompt for AI Agents
In
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/validator/SDJwtValidatorTest.kt
around lines 395-399 (and similarly 550-556), the tests embed full JWT-like
strings that trigger secret scanners; replace these inline JWT fixtures by
moving the full JWTs to resource files (e.g., test-resources under the same
package) and load them with ResourceUtils.getFile, or alternatively
mangle/truncate the payload/signature so they no longer parse as real JWTs while
preserving the parts the validator needs, and update the test to read the
fixture from the resource (or the mangled variant) so CI secret scanners no
longer flag them.

"benefits": "schema:benefits",
"fullName": "schema:name",
"policyExpiresOn": "schema:expires",
"policyIssuedOn": "schema:DateTime",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix incorrect schema.org mapping.

"policyIssuedOn": "schema:DateTime" is incorrect because DateTime is a data type in schema.org, not a property. Consider using an appropriate date property instead:

Apply this diff:

-    "policyIssuedOn": "schema:DateTime",
+    "policyIssuedOn": "schema:dateIssued",

Alternatively, "schema:datePublished" could be appropriate depending on the semantic intent.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"policyIssuedOn": "schema:DateTime",
"policyIssuedOn": "schema:dateIssued",
🤖 Prompt for AI Agents
In
vc-verifier/kotlin/vcverifier/src/test/resources/contexts/insurance-context.json
around line 17, the mapping "policyIssuedOn": "schema:DateTime" is incorrect
because DateTime is a datatype not a property; replace the value with an
appropriate schema.org date property (for example "schema:datePublished" or
"schema:dateCreated" depending on intent) so the mapping becomes
"policyIssuedOn": "schema:datePublished" (or chosen property), and update any
related tests/fixtures to reflect the new property name.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (8)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/data/Data.kt (1)

57-62: Consider using an enum or sealed class for the status field.

The status: Int field uses a magic integer (0 for unrevoked, 1 for revoked based on test assertions). Consider defining a dedicated enum or sealed class for better type safety and self-documenting code:

enum class CredentialStatus(val code: Int) {
    ACTIVE(0),
    REVOKED(1)
    // extend as needed
}

Alternatively, if the integer values must match an external specification, document the expected values inline.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (2)

46-54: Lazy-initialized loader is not cached when documentLoader is null.

When documentLoader is null, a new ConfigurableDocumentLoader is created on every call but not assigned back to documentLoader. If this is intentional (for stateless behavior), consider documenting it. Otherwise, cache the result:

 fun getConfigurableDocumentLoader(): ConfigurableDocumentLoader {
-    return documentLoader ?: run {
+    return documentLoader ?: synchronized(this) {
+        documentLoader ?: run {
             val loader = ConfigurableDocumentLoader()
             loader.isEnableHttps = true
             loader.isEnableHttp = true
             loader.isEnableFile = false
+            documentLoader = loader
             loader
         }
+    }
 }

131-145: Exception type inconsistency in verifyJwt.

Line 133 throws IllegalArgumentException (via require) for invalid JWT format, while lines 142-144 wrap other failures in SignatureVerificationException. Consider consistent exception handling:

-    require(parts.size == 3) { "Invalid JWT format" }
+    if (parts.size != 3) {
+        throw SignatureVerificationException("Invalid JWT format: expected 3 parts, got ${parts.size}")
+    }

This ensures callers only need to handle one exception type for all verification failures.

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt (2)

41-41: Unused logger declaration.

The logger is declared but not used in any test method. Remove it or add logging to tests where appropriate.

-    private val logger = Logger.getLogger(PresentationVerifierTest::class.java.name)

36-39: Consider clearing MockK mocks in teardownAll.

The tests use mockkObject(NetworkManagerClient.Companion) but don't call unmockkObject in cleanup. This could cause test pollution if other test classes run in the same JVM:

 @AfterAll
 fun teardownAll() {
     Util.documentLoader = null
+    io.mockk.unmockkAll()
 }
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/PresentationVerifier.kt (3)

53-139: VP proof verification helper is correct; consider minor maintainability/logging tweaks

The extracted getPresentationVerificationStatus correctly centralizes VP proof verification, and the switch to PublicKeyResolverFactory().get(verificationMethod) plugs cleanly into the existing ED25519 branches with appropriate exception handling.

Two optional improvements you might consider later:

  • Inject PublicKeyResolverFactory (or a PublicKeyResolver abstraction) into PresentationVerifier instead of constructing it ad‑hoc to ease testing and reuse.
  • Log the full exception (e.g., logger.log(Level.SEVERE, "Error while verifying presentation proof", e)) rather than only e.message to preserve stack traces for debugging.

162-171: Status-aware VC mapping mirrors existing path; could share common logic

The implementation cleanly extends getVCVerificationResults by reusing the same verification pipeline and adding credential-status extraction via verifyAndGetCredentialStatus, which keeps backwards compatibility intact.

If you want to reduce duplication later, consider factoring the common “VC JSON → VerificationResult → VerificationStatus + serialized VC” mapping into a shared helper and have both getVCVerificationResults and getVCVerificationResultsWithCredentialStatus build on top of it, with the latter only adding the credentialStatus plumbing.


173-183: New verifyAndGetCredentialStatus API is consistent; clarify statusPurposeList semantics

The new status-aware API is consistent with the existing verify() method and correctly reuses getPresentationVerificationStatus plus the new VC-status helper, so behaviour at both VP and VC levels stays aligned.

Two small follow-ups you might consider:

  • Add brief KDoc documenting how statusPurposeList is interpreted (e.g., empty = “check all supported purposes” vs “skip status checks”) so API users don’t have to infer this from tests or implementation details.
  • Based on learnings, SD‑JWT credentials are expected to bypass status checks via a checkStatus that returns null; it’s good that this API explicitly uses CredentialFormat.LDP_VC, but a short comment in the verifier layer noting that SD‑JWT uses a separate path would make that design intention obvious to future readers.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cf9aef3 and 14c77d1.

📒 Files selected for processing (10)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/PresentationVerifier.kt (6 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/CredentialVerifierConstants.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/data/Data.kt (4 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/LocalDocumentLoader.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (3 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/UtilsTest.kt (3 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/contexts/mock-identity-context.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/vp/VPWithRevokedVC.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/vp/VPWithUnrevokedVC.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • vc-verifier/kotlin/vcverifier/src/test/resources/vp/VPWithRevokedVC.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/LocalDocumentLoader.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/utils/UtilsTest.kt
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: abhip2565
Repo: mosip/vc-verifier PR: 202
File: vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt:18-21
Timestamp: 2025-11-03T12:07:06.442Z
Learning: For SD-JWT credentials in the vc-verifier project, the checkStatus method should return null to bypass status checks rather than throwing errors or implementing actual status verification.
📚 Learning: 2025-11-03T12:07:06.442Z
Learnt from: abhip2565
Repo: mosip/vc-verifier PR: 202
File: vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt:18-21
Timestamp: 2025-11-03T12:07:06.442Z
Learning: For SD-JWT credentials in the vc-verifier project, the checkStatus method should return null to bypass status checks rather than throwing errors or implementing actual status verification.

Applied to files:

  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/PresentationVerifier.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (java-kotlin)
  • GitHub Check: Analyze (java-kotlin)
  • GitHub Check: build-maven-vc-verifier / maven-build
🔇 Additional comments (9)
vc-verifier/kotlin/vcverifier/src/test/resources/vp/VPWithUnrevokedVC.json (1)

96-102: CredentialStatus structure is correctly compatible with LdpStatusChecker expectations.

The JSON file properly uses:

  • statusListIndex as a string (e.g., "104282"), which LdpStatusChecker parses via .toString().toInt() conversion (line 256 of LdpStatusChecker.kt)
  • BitstringStatusListEntry type is recognized by the implementation
  • Fragment-based id notation is standard for status list entries
  • All required fields are present and match the implementation's expectations

This structure aligns with existing test cases in StatusListRevocationCheckerTest.kt that validate the same format across multiple scenarios.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/CredentialVerifierConstants.kt (1)

24-24: LGTM! New P-256/ES256 constants added correctly.

The P256 constant correctly uses the standard NIST curve name "P-256" (secp256r1), and ES256_KEY_TYPE_2019 follows the established naming convention alongside the existing ES256K_KEY_TYPE_2019. These additions properly support the ES256 algorithm verification flow.

Also applies to: 37-40

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/data/Data.kt (2)

17-31: LGTM! New data classes support credential status verification flow.

The new PresentationResultWithCredentialStatus and VCResultWithCredentialStatus classes properly extend the verification result model to include credential status information. The structure aligns with the existing PresentationVerificationResult pattern.


36-36: LGTM! Enum updates are appropriate.

  • Adding REVOKED to VerificationStatus completes the status representation.
  • Renaming DATA_MODEL to DataModel aligns with Kotlin naming conventions (PascalCase for enum classes).

Also applies to: 46-50

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (2)

88-95: LGTM! New HTTPS URI validation helper.

The isValidHttpsUri function correctly validates that a URI uses HTTPS scheme with a non-null host, complementing the existing isValidUri function.


101-111: LGTM! Updated to use renamed DataModel enum.

The getContextVersion function correctly returns DataModel enum values, aligning with the enum rename from DATA_MODEL to DataModel.

vc-verifier/kotlin/vcverifier/src/test/resources/contexts/mock-identity-context.json (1)

1-103: LGTM! Valid JSON-LD context for test resources.

The mock identity context follows JSON-LD 1.1 conventions correctly:

  • Properly defines the MOSIP namespace and vocabulary terms
  • Uses nested @context pattern for language-tagged values
  • Includes both full field names and abbreviated variants for flexibility

This test resource will support the credential verification test scenarios with MockVerifiableCredential types.

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt (1)

116-153: Verification confirmed: tests are correctly designed.

The VPVerificationStatus.INVALID expectation is intentional. Both tests use identical VP files with mock/invalid JWS data (".hello." payload), which correctly fail proof verification while allowing credential status checks to execute independently. The key test difference is the status list response (revoked vs unrevoked), which correctly produces opposite credentialStatus[0].valid values (false for revoked, true for unrevoked). This design properly isolates status verification concerns from proof validation.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/PresentationVerifier.kt (1)

43-51: Refactoring verify() to delegate VP proof verification looks sound

Delegating VP proof verification into getPresentationVerificationStatus keeps verify() simple and ensures both verify paths share identical proof logic. No behavioural regressions visible here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
vc-verifier/kotlin/README.md (2)

800-801: Fix duplicate KB JWT header row.

The error table contains a duplicate "KB JWT header" row (lines 800–801) with the same error code. Remove one row or clarify if a different condition/code was intended.

Apply this diff to remove the duplicate:

  | KB JWT header             | ERR_INVALID_KB_JWT_HEADER          |
- | KB JWT header             | ERR_INVALID_KB_JWT_HEADER          |
  | alg in KB JWT header      | ERR_MISSING_KB_JWT_ALG             |

832-832: Confirm or align catch‑all error code for status checks.

Line 832 uses ERR_INVALID_UNKNOWN as the catch-all, while other error sections use ERR_GENERIC. Please confirm this inconsistency is intentional; if not, align on a single code.

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/StatusListRevocationCheckerTest.kt (1)

267-295: Shut down both MockWebServer instances to avoid test resource leaks.

The test creates two MockWebServer instances (server at line 273 and the unnamed server at line 274) but only shuts down server at line 294. The second server created for replacedVCZero is never shut down, which can cause port/resource leaks.

Apply this diff to fix the leak:

         val (replacedVC, server) = prepareVC(statusListJson = statusListJsonNegative)
-        val (replacedVCZero, _) = prepareVC(
+        val (replacedVCZero, serverZero) = prepareVC(
             statusListJson = statusListJsonZero
         )

         val resultNeg = checker.getStatuses(replacedVC).entries.first()
         
         assertFalse(resultNeg.value.isValid)
         assertEquals(
             StatusCheckErrorCode.STATUS_VERIFICATION_ERROR,
             resultNeg.value.error?.errorCode
         )

         val resultZero = checker.getStatuses(replacedVCZero).entries.first()

         assertFalse(resultZero.value.isValid)
         assertEquals(
             StatusCheckErrorCode.STATUS_VERIFICATION_ERROR,
             resultZero.value.error?.errorCode
         )

         server.shutdown()
+        serverZero.shutdown()
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt (1)

265-278: Prevent negative or overflowing STATUS_LIST_INDEX from reading wrong bits.

The validation at line 307 only checks that STATUS_LIST_INDEX is parseable as an Int but does not enforce non-negativity. Later at line 265, the index is re-parsed, and line 272 computes bitPosition = statusListIndex * statusSize without checking for:

  1. Negative statusListIndex
  2. Integer overflow in the multiplication
  3. Negative bitPosition in the range check at line 273

This can lead to reading from incorrect bit positions.

Apply this diff to add proper validation:

         val statusListIndex = entry[STATUS_LIST_INDEX].toString().toInt()
+        if (statusListIndex < 0) {
+            throw StatusCheckException(
+                "'$STATUS_LIST_INDEX' must be >= 0",
+                INVALID_INDEX
+            )
+        }
         val decodedBitSet = decodeEncodedList(encodedList)
         val totalBits = decodedBitSet.size * 8
         if (totalBits < minimumNumberOfEntries * statusSize) {
             logger.warning("Decoded bitstring shorter than required herd privacy length")
         }

         val bitPosition = statusListIndex * statusSize
-        if (bitPosition >= totalBits) {
+        if (bitPosition < 0 || bitPosition >= totalBits) {
             throw StatusCheckException(
                 "Bit position $bitPosition out of range",
                 RANGE_ERROR
             )
         }
🧹 Nitpick comments (7)
README.md (1)

61-61: Fix list indentation to align with markdown standards.

Lines 61 and 66 have 4-space indentation but should use 2-space indentation per MD007.

Apply this diff:

- `statusChecker`
+ - `statusChecker`
- **keyResolver** - PublicKeyResolverFactory for different type of verification method types are declared in this package.
+ - **keyResolver** - PublicKeyResolverFactory for different type of verification method types are declared in this package.

Also applies to: 66-66

vc-verifier/kotlin/README.md (3)

63-66: Fix markdown list indentation throughout the file.

Multiple list items have 4-space indentation when they should use 2-space indentation per MD007. Additionally, some nested items have incorrect indentation levels (e.g., lines 316–318 use 8 spaces instead of 4).

Apply consistent 2-space indentation for first-level bullets and 4-space for nested items:

- * `LdpValidator` for LDP VC
+ * `LdpValidator` for LDP VC

This pattern applies to all flagged lines. Consider using a markdown linter (e.g., markdownlint --fix) to auto-correct all indentation violations.

Also applies to: 74-79, 174-176, 206-208, 220-221, 262-267, 284-292, 307-318, 489-489, 588-595


708-708: Fix table formatting issues.

Line 708 has a table column count mismatch: the header declares 3 columns but the row contains 4 cells. Line 611 is missing blank lines around a table per MD058.

Apply these fixes:

  • Line 708: Verify the intended table structure and ensure all rows have matching column counts.
  • Line 611: Add blank lines before and after the table.

Also applies to: 611-611


725-725: Replace emphasis with proper headings.

Lines 725, 768, 777, and 817 use bold text (e.g., **ldp_vc Error Codes**) where markdown headings should be used per MD036. Use # syntax instead:

- **ldp_vc Error Codes**
+ ## ldp_vc Error Codes
- **mso_mdoc Format VC Error Codes**
+ ## mso_mdoc Format VC Error Codes
- **vc+sd-jwt/dc+sd-jwt Format VC Error Codes**
+ ## vc+sd-jwt/dc+sd-jwt Format VC Error Codes
- **Status Check Error Codes**
+ ## Status Check Error Codes

Also applies to: 768-768, 777-777, 817-817

vc-verifier/kotlin/vcverifier/src/test/java/testutils/TestUtils.kt (1)

8-9: Consider adding error handling for missing test resources.

The readClasspathFile function will throw an exception if the resource is missing, which is appropriate for tests. However, consider whether a more descriptive error message would help developers debug test failures faster.

Optionally, wrap with a more descriptive error:

fun readClasspathFile(path: String): String =
    try {
        String(Files.readAllBytes(ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + path).toPath()))
    } catch (e: FileNotFoundException) {
        throw AssertionError("Test resource not found: $path", e)
    }
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/CredentialsVerifierTest.kt (1)

66-69: Minor: Formatting inconsistency in multi-line assertEquals.

The assertion spans multiple lines, which is fine, but ensure consistent formatting across all tests.

Consider:

assertEquals("${ERROR_CODE_MISSING}${CONTEXT.uppercase()}", verificationResult.verificationErrorCode)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt (1)

45-45: Remove the empty default constructor.

The empty default constructor can be removed for cleaner code.

Apply this diff:

-class LdpStatusChecker() {
+class LdpStatusChecker {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14c77d1 and 6a990a2.

📒 Files selected for processing (26)
  • README.md (3 hunks)
  • vc-verifier/kotlin/README.md (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/VerifiableCredential.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/LdpVerifiableCredential.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt (0 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/data/Data.kt (4 hunks)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/exception/StatusCheckException.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/CredentialsVerifierTest.kt (8 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt (4 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/StatusListRevocationCheckerTest.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifierTest.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifierTest.kt (4 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/SdJwtVerifierTest.kt (2 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/java/testutils/TestUtils.kt (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/mockDid.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/didEcKey.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/didEdPublicKey.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/didMosipKey.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/httpsMockKey.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/httpsMockKey2.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/idaPublicKey.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/vp/public_key/didIdentityServiceKey.json (1 hunks)
  • vc-verifier/kotlin/vcverifier/src/test/resources/vp/public_key/didMockKey.json (1 hunks)
💤 Files with no reviewable changes (1)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt
✅ Files skipped from review due to trivial changes (3)
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/didMosipKey.json
  • vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/httpsMockKey2.json
  • vc-verifier/kotlin/vcverifier/src/test/resources/vp/public_key/didIdentityServiceKey.json
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: abhip2565
Repo: mosip/vc-verifier PR: 202
File: vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt:18-21
Timestamp: 2025-11-03T12:07:06.442Z
Learning: For SD-JWT credentials in the vc-verifier project, the checkStatus method should return null to bypass status checks rather than throwing errors or implementing actual status verification.
📚 Learning: 2025-11-03T12:07:06.442Z
Learnt from: abhip2565
Repo: mosip/vc-verifier PR: 202
File: vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt:18-21
Timestamp: 2025-11-03T12:07:06.442Z
Learning: For SD-JWT credentials in the vc-verifier project, the checkStatus method should return null to bypass status checks rather than throwing errors or implementing actual status verification.

Applied to files:

  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/VerifiableCredential.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifierTest.kt
  • vc-verifier/kotlin/README.md
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/LdpVerifiableCredential.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/CredentialsVerifierTest.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/exception/StatusCheckException.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/SdJwtVerifierTest.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifierTest.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/StatusListRevocationCheckerTest.kt
  • README.md
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt
🧬 Code graph analysis (4)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/CredentialsVerifierTest.kt (1)
vc-verifier/kotlin/vcverifier/src/test/java/testutils/TestUtils.kt (2)
  • readClasspathFile (8-9)
  • mockHttpResponse (13-17)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifierTest.kt (1)
vc-verifier/kotlin/vcverifier/src/test/java/testutils/TestUtils.kt (2)
  • mockHttpResponse (13-17)
  • readClasspathFile (8-9)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt (1)
vc-verifier/kotlin/vcverifier/src/test/java/testutils/TestUtils.kt (2)
  • readClasspathFile (8-9)
  • mockHttpResponse (13-17)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt (3)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifier.kt (1)
  • verify (32-76)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/SdJwtVerifier.kt (2)
  • verify (9-36)
  • verify (11-15)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifier.kt (1)
  • verify (41-72)
🪛 detekt (1.23.8)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt

[warning] 45-45: An empty default constructor can be removed.

(detekt.empty-blocks.EmptyDefaultConstructor)


[warning] 145-145: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

🪛 markdownlint-cli2 (0.18.1)
vc-verifier/kotlin/README.md

74-74: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


75-75: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


76-76: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


78-78: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


90-90: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


91-91: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


92-92: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


100-100: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


101-101: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


102-102: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


104-104: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


105-105: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


107-107: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


108-108: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


109-109: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


110-110: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


112-112: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


113-113: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


115-115: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


116-116: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


117-117: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


174-174: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


175-175: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


176-176: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


206-206: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


207-207: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


208-208: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


213-213: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


214-214: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


220-220: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


221-221: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


262-262: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


263-263: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


267-267: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


270-270: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


284-284: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


285-285: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


290-290: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


291-291: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


292-292: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


307-307: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


308-308: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


312-312: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


314-314: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


315-315: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


316-316: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


317-317: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


318-318: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


489-489: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


588-588: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


589-589: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


591-591: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


592-592: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


593-593: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


594-594: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


595-595: Unordered list indentation
Expected: 6; Actual: 12

(MD007, ul-indent)


611-611: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


708-708: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing

(MD056, table-column-count)


725-725: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


768-768: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


777-777: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


817-817: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

README.md

61-61: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


66-66: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: publish-snapshot / maven-android-build
  • GitHub Check: Analyze (java-kotlin)
  • GitHub Check: Analyze (java-kotlin)
  • GitHub Check: build-maven-vc-verifier / maven-build
🔇 Additional comments (43)
vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/idaPublicKey.json (1)

1-7: LGTM!

The test resource structure is valid and appropriate for testing RSA public key resolution. The JSON-LD format aligns with W3C security vocabulary standards.

vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/didEcKey.json (1)

1-28: LGTM!

The DID document structure is valid and follows the W3C DID specification. The EC secp256k1 key format is appropriate for testing elliptic curve-based verification flows.

vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/mockDid.json (1)

1-42: LGTM!

The DID document provides comprehensive test coverage with three different key types (RSA, EC secp256k1, Ed25519) using different representation formats (PEM, JWK, Multibase). This is valuable for testing heterogeneous key resolution scenarios.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/msomdoc/MsoMdocVerifiableCredential.kt (1)

54-54: LGTM - Improved immutability.

Changing cbors from MutableList to List is a good practice that prevents unintended mutations and aligns with Kotlin immutability best practices.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/exception/StatusCheckException.kt (2)

3-3: LGTM - Well-structured exception class.

The exception design properly captures both error message and error code, enabling both human-readable messaging and programmatic error handling.


5-16: LGTM - Comprehensive error code coverage.

The error codes cover all relevant failure scenarios in the status-check flow, including encoding/decoding errors, validation errors, and retrieval failures.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/VerifiableCredential.kt (1)

9-11: Breaking API change - migration from revocation to status checks.

The interface now provides checkStatus instead of isRevoked. The default implementation throws UnsupportedOperationException, which is appropriate for credential formats that don't support status checking (e.g., MSO MDOC).

Note: Based on learnings, some credential types (like SD-JWT) should return null to bypass status checks, while others (like MSO MDOC) throw this exception.

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/MsoMdocVerifierTest.kt (2)

18-19: LGTM - Good test data refactoring.

Extracting the valid MDOC credential to a reusable field improves test maintainability and reduces duplication.


105-112: LGTM - Appropriate test coverage for unsupported operation.

The test correctly validates that MSO MDOC credentials throw UnsupportedOperationException when status checking is attempted, consistent with the interface default behavior.

vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/httpsMockKey.json (1)

1-7: LGTM!

The test resource structure is valid and appropriate for testing HTTPS-based public key resolution. The format aligns with W3C security vocabulary standards.

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/SdJwtVerifierTest.kt (1)

3-7: LGTM! Explicit imports improve clarity.

Replacing wildcard imports with explicit assertion imports is a good practice that makes dependencies clearer.

vc-verifier/kotlin/vcverifier/src/test/resources/ldp_vc/public_key/didEdPublicKey.json (1)

1-26: LGTM! Valid DID document structure.

The test resource provides a well-formed DID document with:

  • Proper Ed25519VerificationKey2020 verification method
  • Correct context for Ed25519-2020 suite
  • Valid publicKeyMultibase encoding
  • Appropriate authentication and assertionMethod references
vc-verifier/kotlin/vcverifier/src/test/resources/vp/public_key/didMockKey.json (1)

1-42: LGTM! Comprehensive multi-algorithm DID document.

This test resource provides excellent coverage for testing multiple signature algorithms:

  • RSA (RsaVerificationKey2018)
  • ECDSA secp256k1 (EcdsaSecp256k1VerificationKey2019)
  • Ed25519 (Ed25519VerificationKey2020)

The structure is valid and properly formatted for DID verification testing.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/LdpVerifiableCredential.kt (1)

19-21: LGTM! Clean migration to credential-status architecture.

The implementation properly:

  • Replaces the old isRevoked method with checkStatus
  • Returns the new Map<String, CredentialStatusResult> type
  • Delegates to LdpStatusChecker for status retrieval
  • Accepts optional statusPurposes parameter for filtering

This aligns with the PR's objective to adopt a credential-status architecture and is consistent with the broader status-check refactoring across the codebase.

Based on learnings, the approach differs correctly from SD-JWT credentials (which return null to bypass status checks).

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/CredentialsVerifierTest.kt (4)

29-43: LGTM! Proper test lifecycle management.

The test class correctly:

  • Uses @TestInstance(PER_CLASS) for shared setup/teardown
  • Mocks NetworkManagerClient in setup
  • Configures LocalDocumentLoader for test context loading
  • Resets the document loader in teardown

This ensures tests don't interfere with each other and external HTTP calls are properly mocked.


157-168: LGTM! Correct test for verification failure scenario.

The test properly validates that when VC verification fails, the status list remains empty. This is the correct behavior since status checks should only proceed after successful verification.


170-199: LGTM! Comprehensive status-check test for unrevoked VC.

The test properly:

  • Mocks both the status list endpoint and DID document
  • Verifies the credential and retrieves status
  • Asserts the status result indicates "revocation" purpose with isValid = true
  • Checks that no error is present

201-227: LGTM! Comprehensive status-check test for revoked VC.

The test properly validates the revoked credential scenario by:

  • Mocking the revoked status list and DID document
  • Asserting the status result indicates "revocation" purpose with isValid = false
  • Verifying no error is present in the result
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/LdpVerifierTest.kt (2)

23-36: LGTM! Clean test lifecycle setup.

The test class properly:

  • Uses @TestInstance(PER_CLASS) for shared setup/teardown
  • Configures LocalDocumentLoader for context loading
  • Mocks NetworkManagerClient for HTTP calls
  • Preloads mock public keys in setup
  • Resets document loader in teardown

98-104: LGTM! Centralized mock key setup.

The loadMockPublicKeys helper consolidates all public key mocking in one place, making it easier to maintain and understand which keys are available for tests.

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/PresentationVerifierTest.kt (4)

27-39: LGTM! Consistent test lifecycle management.

The setup mirrors the pattern used in other test files:

  • Mocks NetworkManagerClient
  • Configures LocalDocumentLoader
  • Properly resets state in teardown

101-127: Verify that VPVerificationStatus.INVALID is the expected status for revoked VCs.

The test asserts VPVerificationStatus.INVALID at line 119, but the VC verification itself succeeds (VerificationStatus.SUCCESS at line 121). This suggests the VP proof verification fails, not the credential status check.

Is this the intended behavior? If the VP proof should be valid but the VC is revoked, the status might need adjustment.

Please clarify:

  1. Should a revoked VC cause the VP proof verification to be INVALID?
  2. Or should the VP proof be VALID with the VC status indicating revocation separately?

129-154: Same verification concern: check VPVerificationStatus.INVALID expectation.

Similar to the previous test, this asserts VPVerificationStatus.INVALID at line 146 while the VC verification succeeds. Please confirm this is the expected behavior for unrevoked credentials.


44-52: LGTM! Test updated to use new test utilities.

The migration to readClasspathFile is consistent with the test infrastructure improvements across the PR.

vc-verifier/kotlin/vcverifier/src/test/java/testutils/TestUtils.kt (1)

13-16: Mock properly covers all sendHTTPRequest invocation scenarios.

All production code calls sendHTTPRequest with only 2 parameters (URL and HttpMethod.GET), and the mock in TestUtils.kt correctly uses any() for the second parameter to match this pattern. Verification shows:

  • 3 production call sites (HttpsPublicKeyResolver, DidWebPublicKeyResolver, LdpStatusChecker) all use GET method with 2 parameters
  • All test files properly mock these calls either via mockHttpResponse() helper or direct every blocks
  • No POST calls or additional parameters (bodyParams, headers) used in current codebase
  • The any() matcher appropriately abstracts the HTTP method, allowing both GET and POST if needed in future

The mock setup is correct and comprehensive.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/data/Data.kt (7)

3-4: LGTM!

The import is correctly added to support the new CredentialStatusResult data class that uses StatusCheckException.


17-20: LGTM!

The new data class appropriately extends the presentation result model to include credential status information.


27-31: LGTM!

The design of using Map<String, CredentialStatusResult> allows for multiple status purposes to be checked and reported simultaneously.


36-36: LGTM!

The REVOKED status value is a necessary addition to support the credential status checking infrastructure.


46-50: LGTM!

The rename from DATA_MODEL to DataModel follows Kotlin naming conventions for enum types.


57-60: LGTM!

The data class appropriately models status check results with both validation state and optional error details.


62-65: LGTM!

The summary class provides a convenient aggregation of both verification results and credential status checks.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/CredentialsVerifier.kt (5)

10-11: LGTM!

The imports are correctly added to support the new credential status checking functionality.


18-18: LGTM!

Reusing a single CredentialVerifierFactory instance improves performance by avoiding repeated instantiation.


41-74: Verify the handling of expired credentials in the verification flow.

The updated logic allows expired VCs to proceed to signature verification (lines 44-47 exclude ERROR_CODE_VC_EXPIRED from early rejection). This means:

  • An expired VC will still return verificationStatus = true if the signature is valid
  • The expiry information is conveyed via validationMessage and validationErrorCode

Ensure this behavior aligns with the project's requirements for handling expired credentials. Based on learnings, the design intent seems to separate signature verification from validity checks, but confirm that downstream consumers understand that verificationStatus = true doesn't guarantee the credential is currently valid.


76-91: LGTM!

The method appropriately handles unsupported credential formats by catching UnsupportedOperationException and returning an empty map, allowing graceful degradation. Based on learnings, this aligns with the design for SD-JWT credentials.


93-104: LGTM!

The combined method provides a convenient API for callers who need both signature verification and credential status checks in a single call.

vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/StatusListRevocationCheckerTest.kt (2)

1-46: LGTM!

The test setup appropriately uses MockK to mock credential verification and provides clean helper methods for test data preparation.


82-453: Comprehensive test coverage.

The test suite thoroughly validates the status checker across a wide range of scenarios including success cases, various error conditions, edge cases for validation, and temporal checks. The test names clearly describe the scenarios being tested.

vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/statusChecker/LdpStatusChecker.kt (4)

62-124: LGTM!

The method appropriately handles both single and multiple credentialStatus entries, with proper filtering and error handling per entry.


135-224: LGTM!

The method properly fetches and validates the status list VC, including signature verification, temporal validity checks, and type/purpose validation. The exception wrapping at line 145 is appropriate (not swallowed despite the static analysis hint).


321-356: LGTM!

The decoding and decompression logic properly handles the base64url format with optional 'u' prefix and includes appropriate error handling for both decoding and decompression failures.


285-285: LGTM!

The helper methods for validation are simple and correctly implemented.

Also applies to: 390-391

Comment on lines 32 to 41
@Test
fun `should throw exception for mso_mdoc status check as its not supported`() {
val file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "sd-jwt_vc/sdJwt.txt")
val vc = String(Files.readAllBytes(file.toPath()))
val unsupportedStatusCheckException = assertThrows(UnsupportedOperationException::class.java) {
MsoMdocVerifiableCredential().checkStatus(vc, null)
}

assertEquals("Credential status checking not supported for this credential format",unsupportedStatusCheckException.message)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Test is misplaced and uses incorrect test fixture.

This test verifies MsoMdocVerifiableCredential behavior but:

  • It's located in SdJwtVerifierTest (should be in MsoMdocVerifierTest)
  • It loads an SD-JWT fixture (sd-jwt_vc/sdJwt.txt) to test MSO_MDOC status checking

Move this test to MsoMdocVerifierTest.kt and use an appropriate MSO_MDOC fixture:

-    @Test
-    fun `should throw exception for mso_mdoc status check as its not supported`() {
-        val file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "sd-jwt_vc/sdJwt.txt")
-        val vc = String(Files.readAllBytes(file.toPath()))
-        val unsupportedStatusCheckException = assertThrows(UnsupportedOperationException::class.java) {
-            MsoMdocVerifiableCredential().checkStatus(vc, null)
-        }
-
-        assertEquals("Credential status checking not supported for this credential format",unsupportedStatusCheckException.message)
-    }

In MsoMdocVerifierTest.kt, add:

@Test
fun `should throw exception for mso_mdoc status check as its not supported`() {
    val vc = // use appropriate MSO_MDOC fixture
    val unsupportedStatusCheckException = assertThrows(UnsupportedOperationException::class.java) {
        MsoMdocVerifiableCredential().checkStatus(vc, null)
    }
    
    assertEquals("Credential status checking not supported for this credential format", unsupportedStatusCheckException.message)
}
🤖 Prompt for AI Agents
In
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/SdJwtVerifierTest.kt
around lines 32-41, the test verifying MsoMdocVerifiableCredential is misplaced
and uses an SD-JWT fixture; remove this test from SdJwtVerifierTest and add the
same test to MsoMdocVerifierTest.kt using an MSO_MDOC fixture from test
resources (replace the sd-jwt file load with the appropriate MSO_MDOC resource),
then instantiate MsoMdocVerifiableCredential().checkStatus(vc, null) inside
assertThrows and assert the same error message; ensure the new test file imports
ResourceUtils/Files as needed and the test name and assertions remain identical.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
vc-verifier/kotlin/README.md (2)

816-817: Remove duplicate "KB JWT header" error row.

The error table contains a redundant "KB JWT header" row on lines 816-817 with identical error code. Remove one row to eliminate the accidental duplication.

 | KB JWT header             | ERR_INVALID_KB_JWT_HEADER          |
-| KB JWT header             | ERR_INVALID_KB_JWT_HEADER          |
 | alg in KB JWT header      | ERR_MISSING_KB_JWT_ALG             |

833-848: Standardize catch-all error code: use ERR_GENERIC instead of ERR_INVALID_UNKNOWN.

Line 848 uses ERR_INVALID_UNKNOWN as the fallback for status-check errors, while the LDP VC (line 782) and MSO MDOC (line 791) sections use ERR_GENERIC. This inconsistency may confuse API consumers. Align on a single catch-all code for consistency across all error-code sections.

-For other unknown exceptions, error code will be `ERR_INVALID_UNKNOWN`
+For other unknown exceptions, error code will be `ERR_GENERIC`
🧹 Nitpick comments (2)
vc-verifier/kotlin/README.md (2)

255-255: Convert emphasis formatting to proper markdown headings.

The following lines use bold emphasis (**text**) in place of section headings, which violates markdown best practices (MD036) and breaks document structure for tools that parse heading hierarchy.

Convert each from **Text** to ### Text:

  • Line 255: **Verify and Obtain Credential status**### Verify and Obtain Credential status
  • Line 280: **Verify Credential**### Verify Credential
  • Line 305: **Get Credential Status**### Get Credential Status
  • Line 332: **Deprecated Verify Credentials Method**### Deprecated Verify Credentials Method
  • Line 496: **Verify Presentation**### Verify Presentation
  • Line 593: **Verify Presentation with Credential Status**### Verify Presentation with Credential Status
  • Line 741: **ldp_vc Error Codes**### ldp_vc Error Codes
  • Line 784: **mso_mdoc Format VC Error Codes**### mso_mdoc Format VC Error Codes
  • Line 793: **vc+sd-jwt/dc+sd-jwt Format VC Error Codes**### vc+sd-jwt/dc+sd-jwt Format VC Error Codes
  • Line 833: **Status Check Error Codes**### Status Check Error Codes

Also applies to: 280-280, 305-305, 332-332, 496-496, 593-593, 741-741, 784-784, 793-793, 833-833


73-118: Fix list indentation to comply with MD007 (2-space indent for nested lists).

Multiple nested list items use 4-space indentation when markdown best practice (and markdownlint) expects 2 spaces. Examples:

  • Lines 73–76 (Mandatory field checks)
  • Lines 88–92 (validityInfo validation)
  • Lines 99–117 (SD-JWT validation steps)
  • Lines 206–221 (Status check flow)
  • Lines 268–328 (CredentialVerifier API parameters)

Change all nested bullet points from 4 spaces to 2 spaces:

 * **Mandatory field checks:**
-    * Common: `@context`, ...
-    * v1.1 specific: ...
+  * Common: `@context`, ...
+  * v1.1 specific: ...

Also applies to: 206-221, 268-328

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a990a2 and 462de27.

📒 Files selected for processing (1)
  • vc-verifier/kotlin/README.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: abhip2565
Repo: mosip/vc-verifier PR: 202
File: vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt:18-21
Timestamp: 2025-11-03T12:07:06.442Z
Learning: For SD-JWT credentials in the vc-verifier project, the checkStatus method should return null to bypass status checks rather than throwing errors or implementing actual status verification.
📚 Learning: 2025-11-03T12:07:06.442Z
Learnt from: abhip2565
Repo: mosip/vc-verifier PR: 202
File: vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/SdJwtVerifiableCredential.kt:18-21
Timestamp: 2025-11-03T12:07:06.442Z
Learning: For SD-JWT credentials in the vc-verifier project, the checkStatus method should return null to bypass status checks rather than throwing errors or implementing actual status verification.

Applied to files:

  • vc-verifier/kotlin/README.md
🪛 markdownlint-cli2 (0.18.1)
vc-verifier/kotlin/README.md

74-74: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


75-75: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


76-76: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


78-78: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


90-90: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


91-91: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


92-92: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


100-100: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


101-101: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


102-102: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


104-104: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


105-105: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


107-107: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


108-108: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


109-109: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


110-110: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


112-112: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


113-113: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


115-115: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


116-116: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


117-117: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


174-174: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


175-175: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


176-176: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


206-206: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


207-207: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


208-208: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


213-213: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


214-214: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


220-220: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


221-221: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


255-255: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


268-268: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


269-269: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


273-273: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


276-276: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


280-280: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


292-292: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


293-293: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


298-298: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


299-299: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


300-300: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


305-305: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


317-317: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


318-318: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


322-322: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


324-324: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


325-325: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


326-326: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


327-327: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


328-328: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


332-332: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


496-496: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


503-503: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


593-593: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


604-604: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


605-605: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


607-607: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


608-608: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


609-609: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


610-610: Unordered list indentation
Expected: 4; Actual: 8

(MD007, ul-indent)


611-611: Unordered list indentation
Expected: 6; Actual: 12

(MD007, ul-indent)


627-627: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


724-724: Table column count
Expected: 3; Actual: 4; Too many cells, extra data will be missing

(MD056, table-column-count)


741-741: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


784-784: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


793-793: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


833-833: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: publish-snapshot / maven-android-build
  • GitHub Check: build-maven-vc-verifier / maven-build
  • GitHub Check: Analyze (java-kotlin)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants