Skip to content

Commit

Permalink
refactor: Extracted JWT service to its own file
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoe Maas committed Oct 11, 2024
1 parent 0da2041 commit 432d15a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.sphereon.oid.fed.client.validation

import com.nimbusds.jose.JOSEObjectType
import com.nimbusds.jose.JWSAlgorithm
import com.nimbusds.jose.JWSHeader
import com.nimbusds.jose.JWSSigner
import com.nimbusds.jose.JWSVerifier
import com.nimbusds.jose.crypto.ECDSASigner
import com.nimbusds.jose.crypto.ECDSAVerifier
import com.nimbusds.jose.jwk.ECKey
import com.nimbusds.jwt.JWTClaimsSet
import com.nimbusds.jwt.SignedJWT
import com.sphereon.oid.fed.common.jwt.IJwtService
import com.sphereon.oid.fed.common.jwt.JwtSignInput
import com.sphereon.oid.fed.common.jwt.JwtVerifyInput
import com.sphereon.oid.fed.openapi.models.JWTHeader
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject

class MockJwtService : IJwtService {

override suspend fun sign(input: JwtSignInput): String {
val jwkJsonString = Json.encodeToString(input.key)
val ecJWK = ECKey.parse(jwkJsonString)
val signer: JWSSigner = ECDSASigner(ecJWK)
val jwsHeader = input.header.toJWSHeader()

val signedJWT = SignedJWT(
jwsHeader, JWTClaimsSet.parse(JsonObject(input.payload).toString())
)

signedJWT.sign(signer)
return signedJWT.serialize()
}

override suspend fun verify(input: JwtVerifyInput): Boolean {
try {
val jwkJsonString = Json.encodeToString(input.key)
val ecKey = ECKey.parse(jwkJsonString)
val verifier: JWSVerifier = ECDSAVerifier(ecKey)
val signedJWT = SignedJWT.parse(input.jwt)
val verified = signedJWT.verify(verifier)
return verified
} catch (e: Exception) {
throw Exception("Couldn't verify the JWT Signature: ${e.message}", e)
}
}

private fun JWTHeader.toJWSHeader(): JWSHeader {
val type = typ
return JWSHeader.Builder(JWSAlgorithm.parse(alg)).apply {
type(JOSEObjectType(type))
keyID(kid)
}.build()
}
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
package com.sphereon.oid.fed.client.validation

import com.nimbusds.jose.JOSEObjectType
import com.nimbusds.jose.JWSAlgorithm
import com.nimbusds.jose.JWSHeader
import com.nimbusds.jose.JWSSigner
import com.nimbusds.jose.JWSVerifier
import com.nimbusds.jose.crypto.ECDSASigner
import com.nimbusds.jose.crypto.ECDSAVerifier
import com.nimbusds.jose.jwk.Curve
import com.nimbusds.jose.jwk.ECKey
import com.nimbusds.jose.jwk.gen.ECKeyGenerator
import com.nimbusds.jwt.JWTClaimsSet
import com.nimbusds.jwt.SignedJWT
import com.sphereon.oid.fed.client.OidFederationClientService.TRUST_CHAIN_VALIDATION
import com.sphereon.oid.fed.common.jwt.IJwtService
import com.sphereon.oid.fed.common.jwt.JwtSignInput
import com.sphereon.oid.fed.common.jwt.JwtVerifyInput
import com.sphereon.oid.fed.openapi.models.*
import io.ktor.client.engine.mock.*
import io.ktor.client.engine.mock.MockEngine.Companion.invoke
import io.ktor.http.*
import junit.framework.TestCase.assertTrue
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonObject
Expand All @@ -34,48 +21,11 @@ import java.time.OffsetDateTime
import kotlin.test.Test
import kotlin.test.assertEquals

class JwtServiceImpl : IJwtService {
override suspend fun sign(input: JwtSignInput): String {
val jwkJsonString = Json.encodeToString(input.key)
val ecJWK = ECKey.parse(jwkJsonString)
val signer: JWSSigner = ECDSASigner(ecJWK)
val jwsHeader = input.header.toJWSHeader()

val signedJWT = SignedJWT(
jwsHeader, JWTClaimsSet.parse(JsonObject(input.payload).toString())
)

signedJWT.sign(signer)
return signedJWT.serialize()
}

override suspend fun verify(input: JwtVerifyInput): Boolean {
try {
val jwkJsonString = Json.encodeToString(input.key)
val ecKey = ECKey.parse(jwkJsonString)
val verifier: JWSVerifier = ECDSAVerifier(ecKey)
val signedJWT = SignedJWT.parse(input.jwt)
val verified = signedJWT.verify(verifier)
return verified
} catch (e: Exception) {
throw Exception("Couldn't verify the JWT Signature: ${e.message}", e)
}
}

private fun JWTHeader.toJWSHeader(): JWSHeader {
val type = typ
return JWSHeader.Builder(JWSAlgorithm.parse(alg)).apply {
type(JOSEObjectType(type))
keyID(kid)
}.build()
}
}

class TrustChainValidationTest {

companion object {

val jwtService = JwtServiceImpl()
val jwtService = MockJwtService()

// key pairs
val partyBKeyPair = ECKeyGenerator(Curve.P_256).generate()
Expand Down

0 comments on commit 432d15a

Please sign in to comment.