diff --git a/settings.gradle.kts b/settings.gradle.kts index cad04149..dd094220 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,5 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version("0.6.0") - } dependencyResolutionManagement { @@ -10,9 +9,7 @@ dependencyResolutionManagement { maven { url = uri("https://jitpack.io") } - } } rootProject.name = "eudi-srv-web-verifier-endpoint-23220-4-kt" - diff --git a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/VerifierContext.kt b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/VerifierContext.kt index c890342f..8a7ba137 100644 --- a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/VerifierContext.kt +++ b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/VerifierContext.kt @@ -354,8 +354,8 @@ private fun Environment.clientMetaData(publicUrl: String): ClientMetaData { zkpOption = WalletApi.requestZkpKey(publicUrl), vpFormats = mapOf( "vc+sd-jwt+zkp" to VpFormat(listOf("secp256r1-sha256")), - "mso_mdoc+zkp" to VpFormat(listOf("secp256r1-sha256")) - ) + "mso_mdoc+zkp" to VpFormat(listOf("secp256r1-sha256")), + ), ) } diff --git a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/adapter/input/web/WalletApi.kt b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/adapter/input/web/WalletApi.kt index feb18a99..61514b28 100644 --- a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/adapter/input/web/WalletApi.kt +++ b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/adapter/input/web/WalletApi.kt @@ -64,7 +64,7 @@ class WalletApi( GET(JARM_JWK_SET_PATH, this@WalletApi::handleGetJarmJwks) POST( ZKP_JWK_SET_PATH, - this@WalletApi::handlePostZkpJwk + this@WalletApi::handlePostZkpJwk, ) } @@ -119,7 +119,8 @@ class WalletApi( logger.info( response.fold( { "Verifier UI will poll for Wallet Response" }, - { "Wallet must redirect to ${it.redirectUri}" }) + { "Wallet must redirect to ${it.redirectUri}" }, + ), ) ok().json().bodyValueAndAwait(response.getOrElse { JsonObject(emptyMap()) }) }, diff --git a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/domain/Presentation.kt b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/domain/Presentation.kt index 969c21dd..da07e74b 100644 --- a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/domain/Presentation.kt +++ b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/domain/Presentation.kt @@ -268,7 +268,6 @@ sealed interface Presentation { } } - class TimedOut private constructor( override val id: TransactionId, override val initiatedAt: Instant, @@ -322,7 +321,6 @@ sealed interface Presentation { } } - fun Presentation.isExpired(at: Instant): Boolean { fun Instant.isBeforeOrEqual(at: Instant) = isBefore(at) || this == at return when (this) { diff --git a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/domain/VerifierConfig.kt b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/domain/VerifierConfig.kt index 0583d57d..0df5ccc1 100644 --- a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/domain/VerifierConfig.kt +++ b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/domain/VerifierConfig.kt @@ -78,7 +78,7 @@ sealed interface JarmOption { } data class VpFormat( - val proofType: List + val proofType: List, ) /** @@ -94,7 +94,7 @@ data class ClientMetaData( val subjectSyntaxTypesSupported: List, val jarmOption: JarmOption, val zkpOption: EmbedOption, - val vpFormats: Map + val vpFormats: Map, ) /** diff --git a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/port/input/PostZkpJwkRequest.kt b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/port/input/PostZkpJwkRequest.kt index f4b9f76d..c4158d19 100644 --- a/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/port/input/PostZkpJwkRequest.kt +++ b/src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/port/input/PostZkpJwkRequest.kt @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2023 European Commission + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package eu.europa.ec.eudi.verifier.endpoint.port.input import arrow.core.raise.Raise @@ -14,7 +29,6 @@ import java.security.interfaces.ECPublicKey import java.security.spec.X509EncodedKeySpec import java.util.* - sealed interface ZkpJwkError { data class ProcessingError(val message: String, val error: Throwable) : ZkpJwkError } @@ -23,7 +37,7 @@ data class ChallengeRequest( val id: String, val digest: String, val r: String, - val proofType: String + val proofType: String, ) data class EphemeralKeyResponse( @@ -32,7 +46,7 @@ data class EphemeralKeyResponse( val kty: String, val crv: String, val x: String, - val y: String + val y: String, ) private const val publicKeyPEM = """ @@ -56,10 +70,8 @@ class PostZkpJwkRequestLive( private val storePresentation: StorePresentation, ) : PostZkpJwkRequest { - context(Raise) override suspend operator fun invoke(request: ServerRequest, requestId: RequestId): List { - val pem = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "") val keyBytes = Base64.getDecoder().decode(pem) val keySpec = X509EncodedKeySpec(keyBytes) @@ -93,8 +105,8 @@ class PostZkpJwkRequestLive( kty = "EC", crv = "P-256", x = x, - y = y + y = y, ) } } -} \ No newline at end of file +} diff --git a/src/test/kotlin/eu/europa/ec/eudi/verifier/endpoint/TestContext.kt b/src/test/kotlin/eu/europa/ec/eudi/verifier/endpoint/TestContext.kt index f4f3675c..7685c81a 100644 --- a/src/test/kotlin/eu/europa/ec/eudi/verifier/endpoint/TestContext.kt +++ b/src/test/kotlin/eu/europa/ec/eudi/verifier/endpoint/TestContext.kt @@ -41,6 +41,10 @@ import org.springframework.context.support.GenericApplicationContext import org.springframework.core.annotation.AliasFor import org.springframework.core.io.ClassPathResource import org.springframework.test.context.ContextConfiguration +import java.net.URI +import java.net.URL +import java.net.URLConnection +import java.net.URLStreamHandler import java.security.KeyStore import java.time.Clock import java.time.Instant @@ -64,6 +68,10 @@ object TestContext { RSAKey.load(keystore, "client-id", "".toCharArray()) } } + + class VpFormat + private val vpFormatExample = VpFormat() + private val vpFormats = mapOf("exampleFormat" to vpFormatExample) val clientMetaData = ClientMetaData( jwkOption = ByValue, idTokenSignedResponseAlg = JWSAlgorithm.RS256.name, @@ -71,6 +79,17 @@ object TestContext { idTokenEncryptedResponseEnc = EncryptionMethod.A128CBC_HS256.name, subjectSyntaxTypesSupported = listOf("urn:ietf:params:oauth:jwk-thumbprint", "did:example", "did:key"), jarmOption = ParseJarmOptionNimbus(null, JWEAlgorithm.ECDH_ES.name, "A256GCM")!!, + vpFormats = vpFormats, + zkpOption = EmbedOption.byReference { + URL.of( + URI("tt"), + object : URLStreamHandler() { + override fun openConnection(u: URL?): URLConnection { + TODO("Not yet implemented") + } + }, + ) + }, ) val jarSigningConfig: SigningConfig = SigningConfig(rsaJwk, JWSAlgorithm.RS256) val clientIdScheme = ClientIdScheme.X509SanDns("client-id", jarSigningConfig)