Skip to content

Conversation

@jaswanthkumartw
Copy link

@jaswanthkumartw jaswanthkumartw commented Jan 6, 2026

Summary by CodeRabbit

  • New Features

    • Added support for CBOR Web Token (CWT) credential format verification and a sample app flow demonstrating CWT verification.
  • Enhancements

    • Improved CWT validation with explicit error messages for empty/invalid input and stricter timestamp and structure checks.
    • Added signature verification for COSE-signed credentials.
  • Tests

    • Added comprehensive unit tests covering CWT validation and verification scenarios.
  • Chores

    • Integrated COSE library for cryptographic credential handling.

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

Signed-off-by: jaswanthkumarpolisetty <jaswanthkumar.p@thoughtworks.com>
Signed-off-by: jaswanthkumarpolisetty <jaswanthkumar.p@thoughtworks.com>
Signed-off-by: jaswanthkumarpolisetty <jaswanthkumar.p@thoughtworks.com>
@coderabbitai
Copy link

coderabbitai bot commented Jan 6, 2026

Walkthrough

Adds CWT (CBOR Web Token) verifiable credential support: new validator/verifier classes, enum and constants, factory routing, utilities, tests, COSE dependency, build exclusions, and example app changes to verify CWT hex input.

Changes

Cohort / File(s) Summary
Build & Dependency
vc-verifier/kotlin/.../libs.versions.toml, vc-verifier/kotlin/example/build.gradle.kts, vc-verifier/kotlin/vcverifier/build.gradle.kts
Adds COSE lib version and alias; adds COSE implementation dependency; excludes BouncyCastle artifacts in resolutionStrategy; excludes a META-INF manifest from example packaging. Review dependency resolution and exclusion impact.
API & Constants
vc-verifier/kotlin/vcverifier/src/main/java/.../CredentialFormat.kt, .../CredentialValidatorConstants.kt
Adds CWT_VC enum constant and two new error message constants for CWT validation (empty input, invalid hex).
Factory Routing
vc-verifier/kotlin/vcverifier/src/main/java/.../CredentialVerifierFactory.kt
Factory now returns CwtVerifiableCredential for CredentialFormat.CWT_VC.
CWT Implementation
vc-verifier/kotlin/vcverifier/src/main/java/.../types/CwtVerifiableCredential.kt
New class implementing VerifiableCredential delegating to CwtValidator and CwtVerifier; no-op checkStatus (returns empty map).
Validation Logic
vc-verifier/kotlin/vcverifier/src/main/java/.../validator/CwtValidator.kt
New CWT validator: hex checks, COSE_Sign1 decoding, protected header and payload validation, numeric date checks (exp/nbf/iat), and specific ValidationException usage. Dense logic — review thoroughly.
Verification Logic
vc-verifier/kotlin/vcverifier/src/main/java/.../verifier/CwtVerifier.kt
New verifier: hex→bytes, COSE_Sign1 parsing, extract claims/issuer, resolve public key, verify signature; exposes hexToBytes helper. Cryptographic and key-resolution flow requires careful review.
Utilities
vc-verifier/kotlin/vcverifier/src/main/java/.../utils/Util.kt
Adds hexToBytes() and validateNumericDate() for CBOR/hex helpers; used by validator/verifier.
Example App
vc-verifier/kotlin/example/src/main/java/.../MainActivity.kt
verifyVc() now calls verifier with cwtHex and CredentialFormat.CWT_VC; adds sample cwtHex data.
Tests
vc-verifier/kotlin/vcverifier/src/test/java/.../validator/CwtValidatorTest.kt, .../verifier/CwtVerifierTest.kt
Adds comprehensive CwtValidator tests (many failure cases + success) and a basic CwtVerifierTest scaffold (one active test, commented setup). Review test coverage and mocked setups.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant CV as CredentialVerifier
    participant Cwt as CwtVerifiableCredential
    participant Val as CwtValidator
    participant Ver as CwtVerifier
    participant PKR as PublicKeyResolver
    participant COSE as COSE Lib

    Client->>CV: verify(cwtHex, CWT_VC)
    CV->>Cwt: verify(cwtHex)

    rect rgb(220,235,255)
      Note over Val: Validation Phase
      Cwt->>Val: validate(cwtHex)
      Val->>COSE: decode COSE_Sign1 (hex→bytes)
      COSE-->>Val: CBORObject
      Val->>Val: validate structure, header, payload
      Val->>Val: validate exp/nbf/iat
      Val-->>Cwt: ValidationStatus
    end

    rect rgb(220,255,220)
      Note over Ver: Verification Phase
      Cwt->>Ver: verify(cwtHex)
      Ver->>COSE: decode COSE_Sign1
      COSE-->>Ver: CBORObject
      Ver->>Ver: extract issuer & signature
      Ver->>PKR: resolvePublicKey(issuer)
      PKR-->>Ver: PublicKey
      Ver->>Ver: verify signature
      Ver-->>Cwt: Boolean
    end

    Cwt-->>CV: VerificationResult
    CV-->>Client: result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • swatigoel
  • abhip2565

Poem

🐰 A hop, a nibble, a COSE-shaped clue,

Hex bytes tumble, then signatures true;
Validators count dates, verifiers find keys,
I twirl my whiskers through CBOR and COSE breeze —
New credentials verified, a happy rabbit please!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title contains a typo ('cwt formet' should be 'cwt format') and is slightly vague about the scope, but clearly refers to the main change: adding CWT verification and validation support with a new library dependency.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

@jaswanthkumartw jaswanthkumartw changed the title [INJIVER-1369] - Add verification and validation for cwt formet VC [INJIVER-1369] - Add verification and validation for cwt formet VC with new library Jan 6, 2026
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: 8

🤖 Fix all issues with AI Agents
In @vc-verifier/kotlin/gradle/libs.versions.toml:
- Around line 23-24: The jackson dependency versions are inconsistent:
libs.versions.toml sets jacksonAnnotations and jacksonModuleKotlin to 2.17.2
while vcverifier/build.gradle.kts forces jackson-core:2.14.0; update the forced
dependency in build.gradle.kts (the jackson-core version pin around the
dependency declaration) to 2.17.2 to match
jacksonAnnotations/jacksonModuleKotlin, ensure jackson-module-kotlin and
jackson-core are aligned, then run and validate Jackson-dependent code (Kotlin
serialization/deserialization, polymorphic JsonTypeInfo, enum handling and any
code that may be affected by StreamRead/Write and coercion changes) to address
breaking changes introduced between 2.14.0 and 2.17.2.

In @vc-verifier/kotlin/vcverifier/build.gradle.kts:
- Around line 76-81: The global exclusions in the configurations.all block are
removing the same BouncyCastle artifact you explicitly add via
implementation(libs.bouncyCastle) and conflict with other configurations.all
blocks; replace the global exclusions with per-dependency excludes on the
dependencies that bring in the unwanted bcprov/bcpkix/bcutil transitive
artifacts (e.g., update implementation(libs.cose.lib) and any other dependency
entries that transitively pull BouncyCastle to add
exclude(group="org.bouncycastle", module="bcprov-jdk15on") /
exclude(group="org.bouncycastle", module="bcpkix-jdk15on") /
exclude(group="org.bouncycastle", module="bcutil-jdk15on") so you can keep
implementation(libs.bouncyCastle) while removing only the conflicting transitive
versions and remove the contradictory configurations.all exclusions.
- Line 68: The dependency declaration implementation(libs.cose.lib) references
se.digg.cose:cose-lib version 2.0.0 which is not on Maven Central; either
confirm the required repository (e.g., Danubetech or JitPack) is added to the
Gradle repositories block or change the version to one that is published (update
the libs.versions or the explicit version in build.gradle.kts). Locate the
implementation(libs.cose.lib) entry and ensure the repository that hosts
se.digg.cose:cose-lib is configured (or replace libs.cose.lib with a resolvable
version) so the project can resolve the dependency during build.

In
@vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt:
- Line 3: The import android.net.Uri in CwtVerifier.kt is unused and
Android-specific; remove the unused import statement from the top of the file
(the line importing android.net.Uri) so the CwtVerifier class and its functions
compile cleanly in non-Android JVM environments.
- Around line 19-26: Remove the duplicate local function hexToBytes from
CwtVerifier and replace its usages with the existing utility: call
Util.hexToBytes(...) (or add the single-function import
io.mosip.vercred.vcverifier.utils.Util.hexToBytes and call hexToBytes(...));
ensure all references inside CwtVerifier that previously called the local
hexToBytes now call the util method and delete the redundant function
definition.
- Around line 139-153: In verify(credential) fix missing error handling around
PublicKeyResolverFactory().get(issuer) by wrapping the call in a try-catch and
returning false if it throws, and also check the returned publicKey for null and
return false before calling verifySignature(coseBytes, publicKey); additionally
remove the unnecessary semicolons after statements (e.g., the semicolons after
decodeCose(...), isValidCoseStructure(...), CBORObject.DecodeFromBytes(...), and
isValidCwtStructure(...)) so the method consistently follows the defensive
return-false pattern.
- Around line 77-117: Dead-code: fetchPublicKey and extractKid implement JWKS
resolution but are never used; either remove them or wire them into the
verification flow. To fix, either delete the unused methods fetchPublicKey(...)
and extractKid(...) (clean up imports) or modify the verify() path that
currently uses PublicKeyResolverFactory to call fetchPublicKey(coseObj,
issuerMetadataJson) (or a new adapter method) and fall back to
PublicKeyResolverFactory if fetchPublicKey returns null; ensure the verify()
caller supplies issuerMetadataJson (parse issuer metadata where needed) and
handle null PublicKey results consistently with existing error handling.

In
@vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifierTest.kt:
- Around line 22-92: The CwtVerifierTest's entire test method `should verify
valid CWT` is commented out leaving CwtVerifier untested; either re-enable and
fix the test, remove it with a TODO and issue, or document why it's disabled. To
fix: restore the test in class `CwtVerifierTest` (uncomment the `should verify
valid CWT` method), ensure necessary imports and test annotations are present,
fix any runtime issues by mocking `Util.httpGet` correctly (the current mock
targets `Util.httpGet(any())` and must return the `issuerMetadataJson` and
`jwksJson` for `"$issuer/.well-known/openid-credential-issuer"` and
`"$issuer/jwks"`), and verify the COSE creation code (references:
`Sign1COSEObject`, `COSEKey`, `ECKey.Builder`, `KeyPairGenerator`) compiles and
the asserted call `CwtVerifier().verify(coseHex)` returns true; alternatively,
if intentionally disabled remove the commented block in `CwtVerifierTest` and
add a single-line TODO with a tracking issue referencing `CwtVerifier` and
`should verify valid CWT`.
🧹 Nitpick comments (11)
vc-verifier/kotlin/example/build.gradle.kts (1)

51-51: Consider documenting the reason for this exclusion.

The exclusion of META-INF/versions/9/OSGI-INF/MANIFEST.MF suggests a duplicate resource conflict, likely introduced by the new COSE library or updated dependencies. While this exclusion is valid, consider adding a comment explaining which dependency causes the conflict to help future maintainers.

🔎 Suggested improvement
             excludes += "/META-INF/{AL2.0,LGPL2.1}"
+            // Exclude duplicate OSGI manifest from cose-lib or transitive dependencies
             excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/CredentialValidatorConstants.kt (1)

55-58: Fix formatting and consider adding error codes for consistency.

Formatting issues:

  • Missing space after = operator on lines 55 and 57 (inconsistent with the rest of the file)
  • Unnecessary blank lines at lines 56 and 58 (breaks the file's consistent spacing pattern)

Optional improvement:
Similar to ERROR_MESSAGE_EMPTY_VC_JSON having a corresponding ERROR_CODE_EMPTY_VC_JSON (lines 36, 42), consider adding error codes for the new CWT constants (e.g., ERROR_CODE_EMPTY_VC_CWT and ERROR_CODE_INVALID_HEX_VC_CWT) to maintain consistency across validation error handling.

🔎 Proposed formatting fix
-    const val ERROR_MESSAGE_EMPTY_VC_CWT="${VALIDATION_ERROR}Input VC CWT string is null or empty."
-
-    const val ERROR_MESSAGE_INVALID_HEX_VC_CWT="${VALIDATION_ERROR}Invalid hexadecimal format"
-
+    const val ERROR_MESSAGE_EMPTY_VC_CWT = "${VALIDATION_ERROR}Input VC CWT string is null or empty."
+    const val ERROR_MESSAGE_INVALID_HEX_VC_CWT = "${VALIDATION_ERROR}Invalid hexadecimal format"
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/CwtVerifiableCredential.kt (1)

14-20: Remove unnecessary semicolons and consider documenting the no-op checkStatus.

Kotlin doesn't require semicolons. Additionally, consider adding a TODO comment to checkStatus if status checking for CWT credentials is planned for future implementation, or document why it's intentionally a no-op.

🔎 Proposed fix
     override fun verify(credential: String): Boolean {
-        return CwtVerifier().verify(credential);
+        return CwtVerifier().verify(credential)
     }

+    // TODO: Implement status checking for CWT credentials if required
     override fun checkStatus(credential: String, statusPurposes: List<String>?): Map<String, CredentialStatusResult> {
-        return emptyMap();
+        return emptyMap()
     }
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/validator/CwtValidatorTest.kt (2)

13-15: Remove the empty setup() method.

The empty @BeforeEach method adds no value and was flagged by static analysis.

🔎 Proposed fix
-    @BeforeEach
-    fun setup() {
-    }
-
     private val validator = CwtValidator()

34-46: Consider consistent test naming convention.

Test method names use inconsistent prefixes (validate - vs test -). Consider standardizing to a single pattern for better readability and organization.

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

36-36: Consider making restTemplate private.

Exposing restTemplate as a public val leaks the internal HTTP implementation. If external access is needed, consider providing a factory method or making it internal/private.

🔎 Proposed fix
-    val restTemplate = RestTemplate()
+    private val restTemplate = RestTemplate()

152-159: hexToBytes throws unchecked exception on invalid hex characters.

If the input contains non-hex characters (e.g., "ZZ"), toInt(16) throws NumberFormatException. While CwtValidator validates hex before calling this, other callers may not. Consider adding character validation or documenting the precondition.

🔎 Proposed fix
     fun hexToBytes(hex: String): ByteArray {
         val cleanHex = hex.replace("\\s".toRegex(), "")
         require(cleanHex.length % 2 == 0) { "Invalid hex length" }
+        require(cleanHex.matches("^[0-9a-fA-F]*$".toRegex())) { "Invalid hex characters" }

         return ByteArray(cleanHex.length / 2) { i ->
             cleanHex.substring(i * 2, i * 2 + 2).toInt(16).toByte()
         }
     }

177-183: Consider logging HTTP failures for debuggability.

Silently returning null on any exception (network errors, timeouts, HTTP 4xx/5xx) can make debugging difficult. Consider logging at debug/trace level.

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

130-135: Use isIntegral() instead of isNumber for stricter alg validation.

Per COSE specification, alg must be an integer, not a floating-point number. isNumber returns true for floats as well. Consider using isIntegral() for stricter validation.

🔎 Proposed fix
-        if (!protectedHeader[ALG].isNumber) {
+        if (!protectedHeader[ALG].isIntegral) {
             throw ValidationException(
                 ERROR_INVALID_FIELD + "alg must be an integer",
                 ERROR_CODE_INVALID + "ALG"
             )
         }

204-207: Inconsistency with Util.hexToBytes whitespace handling.

isValidHex rejects any whitespace, but Util.hexToBytes strips whitespace before processing. Consider aligning behavior - either allow whitespace in validation (strip before regex check) or document that whitespace is not permitted.

🔎 Proposed fix to align with Util.hexToBytes
     private fun isValidHex(credential: String): Boolean {
+        val cleanCredential = credential.replace("\\s".toRegex(), "")
         val hexRegex = "^[0-9a-fA-F]+$".toRegex()
-        return credential.matches(hexRegex)
+        return cleanCredential.isNotEmpty() && cleanCredential.matches(hexRegex)
     }
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (1)

14-14: Remove unused import java.net.URL.

🔎 Proposed fix
-import java.net.URL
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf09af6 and ba7a8a2.

📒 Files selected for processing (13)
  • vc-verifier/kotlin/example/build.gradle.kts
  • vc-verifier/kotlin/example/src/main/java/io/mosip/vccred/example/MainActivity.kt
  • vc-verifier/kotlin/gradle/libs.versions.toml
  • vc-verifier/kotlin/vcverifier/build.gradle.kts
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/CredentialFormat.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/constants/CredentialValidatorConstants.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/CredentialVerifierFactory.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/types/CwtVerifiableCredential.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/CwtValidator.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/validator/CwtValidatorTest.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifierTest.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
🧬 Code graph analysis (2)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/validator/CwtValidator.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (2)
  • validateNumericDate (161-175)
  • hexToBytes (152-159)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (2)
  • hexToBytes (152-159)
  • httpGet (177-183)
🪛 detekt (1.23.8)
vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/validator/CwtValidatorTest.kt

[warning] 14-15: This empty block of code can be removed.

(detekt.empty-blocks.EmptyFunctionBlock)

🔇 Additional comments (4)
vc-verifier/kotlin/gradle/libs.versions.toml (1)

30-30: LGTM! New COSE library properly configured.

The new coseLibrary version reference and cose-lib library alias are correctly defined and follow the existing conventions in the version catalog.

Also applies to: 66-66

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

4-4: LGTM! Factory properly extended for CWT format.

The addition of CwtVerifiableCredential to the factory follows the existing pattern and correctly handles the new CredentialFormat.CWT_VC format.

Also applies to: 16-16

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

4-4: LGTM! New credential format added correctly.

The CWT_VC enum constant follows the existing naming pattern and integrates seamlessly with the fromValue() method.

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

24-59: LGTM - Clean validation flow with proper error handling.

The validation structure is well-organized with clear separation between structure validation, header validation, and date validation. Exception-based control flow provides consistent error reporting.

Comment on lines 23 to 24
jacksonAnnotations = "2.17.2"
jacksonModuleKotlin = "2.17.2"
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

❓ Verification inconclusive

Script executed:

#!/bin/bash
# Check for forced Jackson versions in build files
rg -n "jackson-core" --type kotlin -A 2 -B 2

Repository: inji/vc-verifier


Repository: inji/vc-verifier
Exit code: 0

stdout:

vc-verifier/kotlin/vcverifier/build.gradle.kts-10-
vc-verifier/kotlin/vcverifier/build.gradle.kts-11-configurations.all {
vc-verifier/kotlin/vcverifier/build.gradle.kts:12:    resolutionStrategy.force( "com.fasterxml.jackson.core:jackson-core:2.14.0")
vc-verifier/kotlin/vcverifier/build.gradle.kts-13-}
vc-verifier/kotlin/vcverifier/build.gradle.kts-14-

Jackson 2.14.0 to 2.17.2 breaking changes migration guide


Summary of notable breaking changes and migration steps when moving from Jackson 2.14.0 → 2.17.2

Quick guidance

  • Read the official release pages for 2.15, 2.16 and 2.17.2 and test your code against each minor release (2.15 → 2.16 → 2.17.2). [1][2][3]

Breaking / behavioral changes to watch for (actionable items)

  1. Processing limits and stricter parsing defaults
    • New StreamRead/Write constraints (max token lengths, nesting, string length, property-name length) and defaults that may reject extremely large or deeply-nested input. Configure StreamReadConstraints/StreamWriteConstraints on JsonFactory if you need previous behavior. [1][2]
  2. Change to INCLUDE_SOURCE_IN_LOCATION default
    • StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION default changed to false (less source info in exceptions). If you rely on source in error messages, explicitly enable it. [2]
  3. Number/string coercion and parsing stricter rules
    • 2.17 tightened "stringified" number coercion (e.g., "07") and 2.17.2 relaxed some number parsing edge-cases (e.g., trailing dot handling); test numeric deserializations and adjust DeserializationFeature or custom deserializers if needed. [3][2]
  4. JsonTypeInfo and polymorphic type handling
    • New JsonTypeInfo.Value, OptBoolean option, and JsonTypeInfo.Id.SIMPLE_NAME were added; polymorphic/type-id behavior changed in places — validate polymorphic deserialization and adjust annotations/config if necessary. [2]
  5. Enum handling and annotations
    • Improved/changed enum annotation support and enum naming strategies (new @EnumNaming/EnumNamingStrategy in 2.15); tests for enum serialization/deserialization may reveal behavioral differences. [1][2]
  6. Kotlin/Scala modules
    • Module compatibility changes: Kotlin module support ranges changed (2.15→2.16) and Kotlin-specific behaviors (getter/is- names, exception types) changed — upgrade jackson-module-kotlin and re-run Kotlin tests. Scala module updates also in 2.16. [1][2]
  7. Jakarta / Jakarta-RS provider changes
    • Jakarta variants and some provider classes were moved/changed (see jakarta/jax-rs related module refactors). If you use javax→jakarta migrations, check the jakarta-variants of modules. [1][3]
  8. Module and dependency changes
    • Several modules added/adjusted (android-record, jackson-datatype-hibernate6, jackson-module-jsonSchema-jakarta) and transitive dependency updates (SnakeYAML, Woodstox, Guava). Verify classpath conflicts and update dependent modules accordingly. [1][2][3]
  9. Exception and API changes in Kotlin/Java interop
    • Some exceptions replaced (e.g., MissingKotlinParameterException → MismatchedInputException); adjust exception handling if you caught the old types. [2]
  10. Misc bugfixes that may change previously relied-on behavior
  • Numerous bug fixes across databind/core/format modules (see patch notes in 2.16.1 and 2.17.2); some fixes (e.g., JsonSetter handling, JsonNode findValues, Reactor lock issues) can alter runtime behavior — run full regression tests. [2][3]

Recommended migration checklist

  • Upgrade and test incrementally: 2.14.0 → 2.15.x → 2.16.x → 2.17.2. Run unit + integration tests at each step. [1][2][3]
  • Run security/static-analysis and dependency checks for transitive changes (SnakeYAML, Woodstox, Jakarta vs javax).
  • If you parse untrusted input, review and tune new StreamRead/WriteConstraints (token lengths, nesting limits). [1][2]
  • Pin or align modules (jackson-core/databind/annotations and language modules) to the same version series to avoid incompatibilities.
  • Update jackson-module-kotlin / jackson-module-scala to matching versions and re-run language-specific tests. [1][2]
  • Search your codebase for places relying on previous lax parsing (stringified numbers, extremely long tokens, exception classes) and add targeted fixes or config flags.

Primary sources (read in full during migration)

  • Jackson 2.15 release notes (changes, processing limits, enum features, kotlin notes). [1]
  • Jackson 2.16 release notes (INCLUDE_SOURCE_IN_LOCATION default change, StreamWriteConstraints, JsonTypeInfo changes). [2]
  • Jackson 2.17 / 2.17.2 release & patch notes (behavior tweaks, bugfixes). [3]

References
[1] Jackson Release 2.15 — FasterXML/jackson Wiki.
[2] Jackson Release 2.16 (and 2.16.1) — FasterXML/jackson Wiki.
[3] Jackson Release 2.17 and 2.17.2 — FasterXML/jackson Wiki.

If you want, I can produce a tailored checklist for your codebase: tell me which Jackson modules you use (core, databind, kotlin, xml, yaml, etc.) and any areas you’re most concerned about (polymorphism, enums, Kotlin interop, security limits).


Resolve Jackson version mismatch between libs.versions.toml and build.gradle.kts.

The Jackson version has been bumped to 2.17.2 in libs.versions.toml (lines 23-24), but vc-verifier/kotlin/vcverifier/build.gradle.kts line 12 still forces jackson-core:2.14.0, creating a version conflict. This mismatch will cause classpath issues and inconsistent behavior.

Additionally, Jackson 2.14.0 → 2.17.2 includes significant breaking changes that require validation:

  • Stricter parsing defaults (StreamRead/Write constraints on token lengths, nesting depth)
  • Changed default for INCLUDE_SOURCE_IN_LOCATION (affects exception messages)
  • Tightened number/string coercion rules
  • Kotlin module compatibility changes (jackson-module-kotlin must align with jackson-core version)
  • JsonTypeInfo and enum handling modifications

Update build.gradle.kts line 12 to align with the 2.17.2 version, then test Jackson-dependent code, particularly Kotlin-specific serialization/deserialization and polymorphic type handling.

🤖 Prompt for AI Agents
In @vc-verifier/kotlin/gradle/libs.versions.toml around lines 23 - 24, The
jackson dependency versions are inconsistent: libs.versions.toml sets
jacksonAnnotations and jacksonModuleKotlin to 2.17.2 while
vcverifier/build.gradle.kts forces jackson-core:2.14.0; update the forced
dependency in build.gradle.kts (the jackson-core version pin around the
dependency declaration) to 2.17.2 to match
jacksonAnnotations/jacksonModuleKotlin, ensure jackson-module-kotlin and
jackson-core are aligned, then run and validate Jackson-dependent code (Kotlin
serialization/deserialization, polymorphic JsonTypeInfo, enum handling and any
code that may be affected by StreamRead/Write and coercion changes) to address
breaking changes introduced between 2.14.0 and 2.17.2.

implementation(libs.annotation.jvm)
implementation(libs.authelete.sd.jwt)
implementation(libs.threetenbp)
implementation(libs.cose.lib)
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

🌐 Web query:

se.digg.cose:cose-lib 2.0.0 Maven Central availability

💡 Result:

se.digg.cose:cose-lib version 2.0.0 is not published to Maven Central (no 2.0.0 version listed for that G:A). See the project listing (notes that publishing to Maven Central was planned) and the Sonatype Central artifact page (no published versions shown). [1][2]

Sources:
[1] libraries.io project page for se.digg.cose:cose-lib.
[2] Sonatype/Maven Central artifact page for se.digg.cose:cose-lib.


🌐 Web query:

se.digg.cose:cose-lib security vulnerabilities CVE

💡 Result:

I couldn't find any public CVE entries tied to the Maven artifact se.digg.cose:cose-lib. Maven Central / mvnrepository and project pages show the library but list no CVEs/vulnerability entries. Sources: [Maven Central / Sonatype],[MvnRepository],[Libraries.io / project page].

If you want, I can (a) run targeted CVE/NVD searches and vendor advisories for specific versions, or (b) scan a given jar for known vulnerable dependency signatures — which would be more thorough.

Sources:
[1] Maven Central / artifact page (se.digg.cose:cose-lib).
[2] MvnRepository entry for se.digg.cose:cose-lib.
[3] Libraries.io project summary for se.digg.cose:cose-lib.


🏁 Script executed:

grep -r "repository\|maven" vc-verifier/kotlin/vcverifier/build.gradle.kts

Repository: inji/vc-verifier

Length of output: 79


🏁 Script executed:

grep -r "cose" vc-verifier/kotlin/vcverifier/ --include="*.toml" --include="*.gradle.kts"

Repository: inji/vc-verifier

Length of output: 140


🏁 Script executed:

find . -name "libs.versions.toml" -o -name "settings.gradle.kts" | head -5

Repository: inji/vc-verifier

Length of output: 147


🏁 Script executed:

cat gradle/libs.versions.toml 2>/dev/null || cat libs.versions.toml 2>/dev/null || find . -name "libs.versions.toml" -exec cat {} \;

Repository: inji/vc-verifier

Length of output: 4281


🏁 Script executed:

cat vc-verifier/kotlin/settings.gradle.kts

Repository: inji/vc-verifier

Length of output: 738


Version 2.0.0 of se.digg.cose:cose-lib is not available on Maven Central. Verify that this version exists in the configured custom repositories (Danubetech, JitPack) or update to an available version. If the dependency cannot be resolved, the build will fail.

🤖 Prompt for AI Agents
In @vc-verifier/kotlin/vcverifier/build.gradle.kts at line 68, The dependency
declaration implementation(libs.cose.lib) references se.digg.cose:cose-lib
version 2.0.0 which is not on Maven Central; either confirm the required
repository (e.g., Danubetech or JitPack) is added to the Gradle repositories
block or change the version to one that is published (update the libs.versions
or the explicit version in build.gradle.kts). Locate the
implementation(libs.cose.lib) entry and ensure the repository that hosts
se.digg.cose:cose-lib is configured (or replace libs.cose.lib with a resolvable
version) so the project can resolve the dependency during build.

Signed-off-by: jaswanthkumarpolisetty <jaswanthkumar.p@thoughtworks.com>
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: 3

🤖 Fix all issues with AI agents
In
@vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt:
- Around line 19-26: Remove the duplicate hexToBytes function from CwtVerifier
and replace any internal calls to hexToBytes with Util.hexToBytes; specifically,
delete the fun hexToBytes(...) definition in CwtVerifier.kt, add the appropriate
import or fully qualify calls to Util.hexToBytes wherever this local function
was used, and ensure compilation by resolving any missing imports or references
to the Util class.
- Around line 105-129: The call PublicKeyResolverFactory().get(issuer) can
return null; before calling verifySignature(coseBytes, publicKey) add a null
check and throw PublicKeyNotFoundException (or a suitable exception) with a
clear message including the issuer when publicKey is null; ensure the existing
catch block still propagates PublicKeyNotFoundException so callers see the
specific failure rather than a NullPointerException.

In
@vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidWebPublicKeyResolver.kt:
- Around line 40-42: The current use of substring matching in
verificationMethods.find ((it[ID] as? String)?.contains(verificationMethodId) ==
true) can resolve the wrong key; change the matching to exact equality: compare
the ID string exactly to verificationMethodId (or, if you must support
fragment/URI variants, perform a deterministic comparison such as URI
normalization and exact equality or use suffix/fragment-only matching like
endsWith after validating the scheme) so that verificationMethod selection via
verificationMethodId is unambiguous and not order-dependent.
🧹 Nitpick comments (2)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (2)

58-75: Remove unused extractKid method.

This method extracts the Key ID from the COSE header but is never called. The verify() method resolves the public key using only the issuer URI via PublicKeyResolverFactory, bypassing any KID-based resolution.

Either remove this dead code or integrate KID-based key resolution into the verification flow if needed.


28-35: Log swallowed exception in decodeCose.

The caught exception is silently swallowed when CBOR decoding fails. This makes debugging difficult when malformed credentials are provided.

📝 Add logging
    private fun decodeCose(cwtBytes: ByteArray): CBORObject? {
        return try {
            CBORObject.DecodeFromBytes(cwtBytes)
        } catch (e: Exception) {
-
+            logger.warning("Failed to decode COSE object: ${e.message}")
            null
        }
    }

Based on static analysis hints.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ba7a8a2 and 5392095.

📒 Files selected for processing (5)
  • vc-verifier/kotlin/example/src/main/java/io/mosip/vccred/example/MainActivity.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/keyResolver/types/did/DidWebPublicKeyResolver.kt
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifierTest.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.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
🧬 Code graph analysis (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (1)
  • hexToBytes (149-156)
🪛 detekt (1.23.8)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt

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

(detekt.exceptions.SwallowedException)


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

(detekt.exceptions.SwallowedException)

Signed-off-by: jaswanthkumarpolisetty <jaswanthkumar.p@thoughtworks.com>
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: 2

🤖 Fix all issues with AI agents
In
@vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt:
- Around line 29-36: Remove the unused helper method decodeCose: it's never
invoked (verify() calls CBORObject.DecodeFromBytes() directly), so delete the
private fun decodeCose(cwtBytes: ByteArray): CBORObject? declaration and its
body to eliminate dead code; if you prefer keeping an abstraction, refactor
verify() to call decodeCose instead, but do not leave an unused decodeCose
method in the class.
- Around line 64-81: The extractKid(CBORObject) method is unused; either remove
it or wire it into the verification path: update verify() in CwtVerifier to call
extractKid(coseObj) and, when a KID is returned, use it to select the matching
key from the resolved JWKS (prefer the KID-matching JWK when constructing the
public key), falling back to issuer-based resolution if no KID or no match;
ensure null-safe handling and remove extractKid if you choose deletion, along
with any now-unused imports.
🧹 Nitpick comments (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (1)

20-27: Remove duplicate hexToBytes - use Util.hexToBytes instead.

This function duplicates Util.hexToBytes from the utilities package. Maintaining duplicate code violates DRY and increases maintenance burden.

♻️ Proposed fix

Import and use the existing utility:

+import io.mosip.vercred.vcverifier.utils.Util
+
 class CwtVerifier {
 
    private val logger = Logger.getLogger(CwtVerifier::class.java.name)
-    fun hexToBytes(hex: String): ByteArray {
-        val cleanHex = hex.replace("\\s".toRegex(), "")
-        require(cleanHex.length % 2 == 0) { "Invalid hex length" }
-
-        return ByteArray(cleanHex.length / 2) { i ->
-            cleanHex.substring(i * 2, i * 2 + 2).toInt(16).toByte()
-        }
-    }

Then replace the call at line 115:

-            val coseBytes = hexToBytes(credential)
+            val coseBytes = Util.hexToBytes(credential)
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5392095 and 724202a.

📒 Files selected for processing (2)
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifierTest.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • vc-verifier/kotlin/vcverifier/src/test/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifierTest.kt
🧰 Additional context used
🧬 Code graph analysis (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (1)
  • hexToBytes (149-156)
🪛 detekt (1.23.8)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt

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

(detekt.exceptions.SwallowedException)


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

(detekt.exceptions.SwallowedException)

Signed-off-by: jaswanthkumarpolisetty <jaswanthkumar.p@thoughtworks.com>
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: 2

🤖 Fix all issues with AI agents
In
@vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt:
- Around line 48-65: Delete the entire commented-out extractKid method block in
CwtVerifier (the commented function named extractKid) to remove dead code;
ensure no remaining references to extractKid exist in the class or callers, run
a build/compile to confirm nothing breaks, and commit the cleanup so Git history
retains the implementation if needed.
- Around line 106-112: The JavaDoc and exception handling around resolving the
public key are inaccurate: PublicKeyResolverFactory.get(issuer) returns a
non-null PublicKey so remove any null-checks, update the JavaDoc on the val
publicKey statement to state it resolves and returns a non-null PublicKey and
declare/cite that it may throw PublicKeyTypeNotSupportedException (not
PublicKeyNotFoundException), and change the catch/rethrow logic that currently
references PublicKeyNotFoundException to instead catch and handle or rethrow
PublicKeyTypeNotSupportedException so the actual thrown exception is handled
when calling PublicKeyResolverFactory.get and before calling
verifySignature(coseBytes, publicKey).
🧹 Nitpick comments (1)
vc-verifier/kotlin/vcverifier/build.gradle.kts (1)

13-15: Consider using per-dependency exclusions for better maintainability.

Global exclusions in configurations.all work but can be less explicit about which dependencies cause conflicts. Consider applying exclusions directly on dependencies that transitively bring in older BouncyCastle versions (e.g., on line 71's libs.cose.lib).

♻️ Alternative approach with per-dependency exclusions
 configurations.all {
     resolutionStrategy.force( "com.fasterxml.jackson.core:jackson-core:2.14.0")
-    exclude(group = "org.bouncycastle", module = "bcprov-jdk15on")
-    exclude(group = "org.bouncycastle", module = "bcpkix-jdk15on")
-    exclude(group = "org.bouncycastle", module = "bcutil-jdk15on")
 }

Then apply exclusions where they're actually needed:

implementation(libs.cose.lib) {
    exclude(group = "org.bouncycastle", module = "bcprov-jdk15on")
    exclude(group = "org.bouncycastle", module = "bcpkix-jdk15on")
    exclude(group = "org.bouncycastle", module = "bcutil-jdk15on")
}

This makes it clear which dependencies introduce the conflicting BouncyCastle versions.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 724202a and 1de3d02.

📒 Files selected for processing (2)
  • vc-verifier/kotlin/vcverifier/build.gradle.kts
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt
🧰 Additional context used
🧬 Code graph analysis (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/utils/Util.kt (1)
  • hexToBytes (149-156)
🔇 Additional comments (5)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (5)

1-21: LGTM! Clean imports and setup.

The imports are well-organized, and the past issue with the Android-specific import has been properly addressed. Using Util.hexToBytes avoids code duplication.


22-26: LGTM! Correct COSE_Sign1 structure validation.

The validation correctly enforces that COSE_Sign1 must be a 4-element array (protected headers, unprotected headers, payload, signature).


28-46: LGTM! Proper issuer extraction and scheme handling.

The method correctly extracts the issuer claim (CWT claim 1 per RFC 8392) and appropriately handles different URI schemes: DIDs are returned as-is, while HTTP(S) URIs are resolved to their JWKS endpoints.


67-76: LGTM! Correct CWT claims extraction.

The method properly extracts the payload from the COSE_Sign1 structure (index 2) and validates that CWT claims form a CBOR map per RFC 8392.


78-93: LGTM! Signature verification logic is sound.

The method correctly validates the COSE_Sign1 signature using the resolved public key. The safe cast at line 83-84 properly handles type mismatches.

Signed-off-by: jaswanthkumarpolisetty <jaswanthkumar.p@thoughtworks.com>
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 (1)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (1)

76-100: Solid verification flow with correct exception handling.

The main verify() method implements a clean flow:

  1. Hex decode → CBOR decode → Structure validation
  2. Claims & issuer extraction
  3. Public key resolution via factory
  4. Signature verification

The exception handling at lines 90-98 is correct: specific exceptions (PublicKeyNotFoundException, SignatureVerificationException) are propagated, while unexpected exceptions are wrapped in UnknownException with context. The static analysis warning about "SwallowedException" is a false positive—no exceptions are silently discarded.

Minor consideration: Line 87 instantiates a new PublicKeyResolverFactory() on every verification. If the factory is stateless, this is fine. If it has initialization overhead or caches, consider making it a class-level property.

Based on learnings, PublicKeyResolverFactory().get(issuer) throws PublicKeyNotFoundException when resolution fails (rather than returning null), so the current exception handling is appropriate.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1de3d02 and c967142.

📒 Files selected for processing (2)
  • vc-verifier/kotlin/gradle/libs.versions.toml
  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • vc-verifier/kotlin/gradle/libs.versions.toml
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-07T10:57:30.150Z
Learnt from: jaswanthkumartw
Repo: inji/vc-verifier PR: 216
File: vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt:95-123
Timestamp: 2026-01-07T10:57:30.150Z
Learning: In the CwtVerifier class, the `PublicKeyResolverFactory().get(issuer)` method throws `PublicKeyNotFoundException` when a key cannot be resolved, rather than returning null.

Applied to files:

  • vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt
🪛 detekt (1.23.8)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt

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

(detekt.exceptions.SwallowedException)

🔇 Additional comments (4)
vc-verifier/kotlin/vcverifier/src/main/java/io/mosip/vercred/vcverifier/credentialverifier/verifier/CwtVerifier.kt (4)

22-26: LGTM! Correct COSE_Sign1 structure validation.

The validation correctly checks that the COSE object is an array with exactly 4 elements (protected headers, unprotected headers, payload, and signature), per the COSE_Sign1 specification.


48-57: LGTM! Correct CWT claims extraction and validation.

The method correctly extracts the payload from index 2 of the COSE_Sign1 array, decodes it as CBOR, and validates it's a map structure containing the CWT claims.


59-74: LGTM! Correct COSE signature verification.

The signature verification correctly:

  • Decodes and validates the COSE_Sign1 object structure
  • Creates a COSEKey from the resolved public key (with null algorithm parameter to infer from COSE headers)
  • Verifies the signature using the COSE library's validate() method

28-46: The implementation correctly follows RFC 8615 standards for well-known resource resolution. Using URI.resolve("/.well-known/jwks.json") with an absolute path is intentional—the JWKS endpoint should be at the domain root regardless of the issuer's path structure. For example, https://api.collab.mosip.net/tenant1 correctly resolves to https://api.collab.mosip.net/.well-known/jwks.json, which is the expected behavior.

Regarding the URISyntaxException at line 40: while an explicit catch with a more descriptive error message would be a minor improvement, the exception is already handled by the outer try-catch block at line 90 and converted to UnknownException, which is acceptable error handling.

Likely an incorrect or invalid review comment.

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.

1 participant