Skip to content

Commit 7af4d7c

Browse files
refactor: add encryption support check in JWEHandler
Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
1 parent 8b5bfcc commit 7af4d7c

7 files changed

Lines changed: 136 additions & 5 deletions

File tree

kotlin/openID4VP/src/commonMain/kotlin/io/mosip/openID4VP/authorizationResponse/AuthorizationResponse.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fun AuthorizationResponse.toJsonEncodedMap(): Map<String, String> {
4848
}
4949

5050
fun AuthorizationResponse.toMap(): Map<String, Any> {
51-
val objectMapper = getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL)
51+
val objectMapper = getObjectMapper().copy().setSerializationInclusion(JsonInclude.Include.NON_NULL)
5252
return when (this) {
5353
is AuthorizationResponse.PresentationExchange -> buildMap {
5454
put("vp_token", objectMapper.convertValue(vpToken, object : TypeReference<Any>() {}))

kotlin/openID4VP/src/commonMain/kotlin/io/mosip/openID4VP/exceptions/openId4VPExceptions.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@ sealed class OpenID4VPExceptions(
181181
className
182182
)
183183

184+
class UnsupportedOperationException(message: String, className: String) :
185+
OpenID4VPExceptions(
186+
INVALID_REQUEST,
187+
message,
188+
className
189+
)
190+
184191
class JweEncryptionFailure(message: String, className: String, cause: Throwable? = null) :
185192
OpenID4VPExceptions(
186193
INVALID_REQUEST,

kotlin/openID4VP/src/commonMain/kotlin/io/mosip/openID4VP/jwt/jwe/JWEHandler.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ class JWEHandler(
2222
) {
2323

2424
fun generateEncryptedResponse(payload: Map<String, Any>): String {
25+
if (keyEncryptionAlg != "ECDH-ES" || contentEncryptionAlg != "A256GCM") {
26+
throw OpenID4VPExceptions.UnsupportedOperationException(
27+
"Unsupported encryption configuration: keyEncryptionAlgorithm=$keyEncryptionAlg, contentEncryptionAlgorithm=$contentEncryptionAlg. Supported configuration: keyEncryptionAlgorithm=ECDH-ES, contentEncryptionAlgorithm=A256GCM",
28+
className
29+
)
30+
}
2531
try {
2632
val header = JWEHeader.Builder(
2733
JWEAlgorithm.parse(keyEncryptionAlg),

kotlin/openID4VP/src/commonMain/kotlin/io/mosip/openID4VP/jwt/jwe/encryption/EncryptionProvider.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ object EncryptionProvider {
5050
)
5151
) {
5252
throw OpenID4VPExceptions.JweEncryptionFailure(
53-
className,
54-
"Unsupported recipient key type: ${jwk.kty}"
53+
"Unsupported EC curve for ECDH-ES: ${jwk.crv}. Only P-256, P-384, P-521 are supported.",
54+
className
5555
)
5656
}
5757

kotlin/openID4VP/src/commonTest/kotlin/io/mosip/openID4VP/authorizationResponse/AuthorizationResponseTest.kt

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,96 @@ class AuthorizationResponseTest {
6161
assertTrue(map.containsKey("presentation_submission"))
6262
assertFalse(map.containsKey("state"))
6363
}
64+
65+
@Test
66+
fun `toMap should filter out null values`() {
67+
val responseWithNullState = AuthorizationResponse.PresentationExchange(
68+
presentationSubmission = presentationSubmission,
69+
vpToken = vpToken,
70+
state = null
71+
)
72+
val map = responseWithNullState.toMap()
73+
assertEquals(2, map.size)
74+
assertTrue(map.containsKey("vp_token"))
75+
assertTrue(map.containsKey("presentation_submission"))
76+
assertFalse(map.containsKey("state"))
77+
}
78+
79+
@Test
80+
fun `toMap should return exact expected map`() {
81+
val expectedVpTokenMap = mapOf(
82+
"@context" to listOf("context"),
83+
"type" to listOf("type"),
84+
"verifiableCredential" to listOf("VC1"),
85+
"id" to "id",
86+
"holder" to "holder",
87+
"proof" to mapOf(
88+
"type" to "type",
89+
"created" to "time",
90+
"challenge" to "challenge",
91+
"domain" to "domain",
92+
"proofValue" to "eryy....ewr",
93+
"proofPurpose" to "authentication",
94+
"verificationMethod" to "did:example:holder#key-1"
95+
)
96+
)
97+
98+
val expectedPresentationSubmissionMap = mapOf(
99+
"id" to "ps_id",
100+
"definition_id" to "client_id",
101+
"descriptor_map" to listOf(
102+
mapOf(
103+
"id" to "input_descriptor_1",
104+
"format" to "ldp_vp",
105+
"path" to "$",
106+
"path_nested" to mapOf(
107+
"id" to "input_descriptor_1",
108+
"format" to "ldp_vp",
109+
"path" to "$.verifiableCredential[0]"
110+
)
111+
)
112+
)
113+
)
114+
115+
val expectedMap = mapOf(
116+
"vp_token" to expectedVpTokenMap,
117+
"presentation_submission" to expectedPresentationSubmissionMap,
118+
"state" to "state"
119+
)
120+
121+
val actualMap = authorizationResponse.toMap()
122+
assertEquals(expectedMap, actualMap)
123+
}
124+
125+
@Test
126+
fun `toMap should return objects for Dcql response`() {
127+
val dcqlResponse = AuthorizationResponse.Dcql(
128+
vpToken = mapOf("credential1" to listOf(ldpVPToken)),
129+
state = "state_123"
130+
)
131+
val expectedVpTokenMap = mapOf(
132+
"@context" to listOf("context"),
133+
"type" to listOf("type"),
134+
"verifiableCredential" to listOf("VC1"),
135+
"id" to "id",
136+
"holder" to "holder",
137+
"proof" to mapOf(
138+
"type" to "type",
139+
"created" to "time",
140+
"challenge" to "challenge",
141+
"domain" to "domain",
142+
"proofValue" to "eryy....ewr",
143+
"proofPurpose" to "authentication",
144+
"verificationMethod" to "did:example:holder#key-1"
145+
)
146+
)
147+
148+
val expectedMap = mapOf(
149+
"vp_token" to mapOf("credential1" to listOf(expectedVpTokenMap)),
150+
"state" to "state_123"
151+
)
152+
153+
val actualMap = dcqlResponse.toMap()
154+
assertEquals(expectedMap, actualMap)
155+
}
64156
}

kotlin/openID4VP/src/commonTest/kotlin/io/mosip/openID4VP/jwt/jwe/JWEHandlerTest.kt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,32 @@ class JWEHandlerTest {
7474
val exception = assertFailsWith<OpenID4VPExceptions.JweEncryptionFailure> {
7575
handler.generateEncryptedResponse(payload)
7676
}
77-
assertEquals(true, exception.message?.startsWith("JWE Encryption failed"))
77+
assertTrue(exception.message!!.contains("JWE Encryption failed"))
78+
}
79+
80+
@Test
81+
fun `should throw UnsupportedOperationException when keyEncryptionAlg is unsupported`() {
82+
val payload = mapOf("key1" to "value1")
83+
val handler = JWEHandler("RSA-OAEP", "A256GCM", publicKey, walletNonce, verifierNonce)
84+
85+
val exception = assertFailsWith<OpenID4VPExceptions.UnsupportedOperationException> {
86+
handler.generateEncryptedResponse(payload)
87+
}
88+
89+
val expectedMessage = "Unsupported encryption configuration: keyEncryptionAlgorithm=RSA-OAEP, contentEncryptionAlgorithm=A256GCM. Supported configuration: keyEncryptionAlgorithm=ECDH-ES, contentEncryptionAlgorithm=A256GCM"
90+
assertTrue(exception.message.contains(expectedMessage))
91+
}
92+
93+
@Test
94+
fun `should throw UnsupportedOperationException when contentEncryptionAlg is unsupported`() {
95+
val payload = mapOf("key1" to "value1")
96+
val handler = JWEHandler("ECDH-ES", "A128GCM", publicKey, walletNonce, verifierNonce)
97+
98+
val exception = assertFailsWith<OpenID4VPExceptions.UnsupportedOperationException> {
99+
handler.generateEncryptedResponse(payload)
100+
}
101+
102+
val expectedMessage = "Unsupported encryption configuration: keyEncryptionAlgorithm=ECDH-ES, contentEncryptionAlgorithm=A128GCM. Supported configuration: keyEncryptionAlgorithm=ECDH-ES, contentEncryptionAlgorithm=A256GCM"
103+
assertTrue(exception.message.contains(expectedMessage))
78104
}
79105
}

kotlin/openID4VP/src/commonTest/kotlin/io/mosip/openID4VP/jwt/jwe/encryption/EncryptionProviderTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class EncryptionProviderTest {
6363
// Current implementation populates class name as the exception message in this branch.
6464
assertOpenId4VPException(
6565
exception,
66-
expectedMessage = "EncryptionProvider",
66+
expectedMessage = "Unsupported EC curve for ECDH-ES: secp256k1. Only P-256, P-384, P-521 are supported.",
6767
expectedErrorCode = OpenID4VPErrorCodes.INVALID_REQUEST
6868
)
6969
}

0 commit comments

Comments
 (0)