@@ -162,6 +162,7 @@ class Wallet2MoreUseCasesTest {
162162 credentialRequestValidator = DefaultCredentialRequestValidator (),
163163 credentialEndpointHandlers = CredentialEndpointHandlers ()
164164 ))
165+ val proofSupport = TestIssuerProofSupport (issuerBase, accessTokenKey)
165166 runBlocking {
166167 preAuthRepo.save(DefaultPreAuthorizedCodeRecord (
167168 code = preAuthCode, clientId = null , txCode = null , txCodeValue = null ,
@@ -193,14 +194,23 @@ class Wallet2MoreUseCasesTest {
193194 get(" /.well-known/oauth-authorization-server" ) { call.respond(AuthorizationServerMetadata (issuer = issuerBase, authorizationEndpoint = " $issuerBase /authorize" , tokenEndpoint = " $issuerBase /token" , responseTypesSupported = setOf (" code" ), grantTypesSupported = setOf (" urn:ietf:params:oauth:grant-type:pre-authorized_code" ))) }
194195 get(" /.well-known/openid-configuration" ) { call.respond(AuthorizationServerMetadata (issuer = issuerBase, authorizationEndpoint = " $issuerBase /authorize" , tokenEndpoint = " $issuerBase /token" , responseTypesSupported = setOf (" code" ), grantTypesSupported = setOf (" urn:ietf:params:oauth:grant-type:pre-authorized_code" ))) }
195196 get(" /credential-offer-json" ) { call.respond(offer) }
197+ post(" /nonce" ) {
198+ val nonce = proofSupport.issueNonce()
199+ call.response.header(HttpHeaders .CacheControl , " no-store" )
200+ call.respond(buildJsonObject {
201+ put(" c_nonce" , nonce.nonce)
202+ put(" c_nonce_expires_in" , nonce.expiresInSeconds)
203+ })
204+ }
196205 post(" /token" ) {
197206 val params = call.receiveParameters()
198207 val code = params[" pre-authorized_code" ] ? : return @post call.respond(HttpStatusCode .BadRequest , buildJsonObject { put(" error" ," invalid_request" ) })
199208 val tr = provider.createAccessTokenRequest(mapOf (" grant_type" to listOf (" urn:ietf:params:oauth:grant-type:pre-authorized_code" ), " pre-authorized_code" to listOf (code), " client_id" to listOf (params[" client_id" ] ? : " wallet-client" )))
200209 if (tr !is AccessTokenRequestResult .Success ) return @post call.respond(HttpStatusCode .BadRequest , buildJsonObject { put(" error" ," invalid_grant" ) })
201210 val resp = provider.createAccessTokenResponse(tr.request.withIssuer(issuerBase))
202211 if (resp !is AccessTokenResponseResult .Success ) return @post call.respond(HttpStatusCode .InternalServerError , buildJsonObject { put(" error" ," server_error" ) })
203- call.respond(buildJsonObject { put(" access_token" , resp.response.accessToken); put(" token_type" , " Bearer" ); put(" c_nonce" , " nonce-$preAuthCode " ); put(" c_nonce_expires_in" , 300 ) })
212+ val nonce = proofSupport.issueNonce()
213+ call.respond(buildJsonObject { put(" access_token" , resp.response.accessToken); put(" token_type" , " Bearer" ); put(" c_nonce" , nonce.nonce); put(" c_nonce_expires_in" , nonce.expiresInSeconds) })
204214 }
205215 post(" /credential" ) {
206216 val body = json.parseToJsonElement(call.receiveText()).jsonObject
@@ -219,29 +229,41 @@ class Wallet2MoreUseCasesTest {
219229 return @post
220230 }
221231
232+ val request = cr.request.withIssuer(issuerBase)
222233 val credResp = provider.createCredentialResponse(
223- request = cr. request.withIssuer(issuerBase) ,
234+ request = request,
224235 configuration = configuration, issuerKey = issuerKey,
225236 issuerId = issuerBase, credentialData = credentialData,
226- selectiveDisclosure = selectiveDisclosure
237+ selectiveDisclosure = selectiveDisclosure,
238+ proofValidationContext = proofSupport.validationContext(request)
227239 )
228- if (credResp !is CredentialResponseResult .Success ) return @post call.respond(HttpStatusCode .InternalServerError , buildJsonObject { put(" error" ," server_error" ) })
229- val httpResp = provider.writeCredentialResponse(cr.request.withIssuer(issuerBase), credResp.response)
240+ if (credResp !is CredentialResponseResult .Success ) {
241+ val failure = credResp as CredentialResponseResult .Failure
242+ val httpResp = provider.writeCredentialError(request, failure.error)
243+ return @post call.respond(HttpStatusCode .fromValue(httpResp.status), httpResp.payload)
244+ }
245+ val httpResp = provider.writeCredentialResponse(request, credResp.response)
230246 call.respond(HttpStatusCode .fromValue(httpResp.status), httpResp.payload)
231247 }
232248 post(" /deferred-credential" ) {
233249 val body = json.parseToJsonElement(call.receiveText()).jsonObject
234250 val txId = body[" transaction_id" ]?.jsonPrimitive?.content ? : return @post call.respond(HttpStatusCode .BadRequest , buildJsonObject { put(" error" ," invalid_transaction_id" ) })
235251 val (origRequest, data) = deferredCredentials.remove(txId) ? : return @post call.respond(HttpStatusCode .BadRequest , buildJsonObject { put(" error" ," invalid_transaction_id" ) })
236252
253+ val request = origRequest.withIssuer(issuerBase)
237254 val credResp = provider.createCredentialResponse(
238- request = origRequest.withIssuer(issuerBase) ,
255+ request = request ,
239256 configuration = configuration, issuerKey = issuerKey,
240257 issuerId = issuerBase, credentialData = data,
241- selectiveDisclosure = null
258+ selectiveDisclosure = null ,
259+ proofValidationContext = proofSupport.validationContext(request)
242260 )
243- if (credResp !is CredentialResponseResult .Success ) return @post call.respond(HttpStatusCode .InternalServerError , buildJsonObject { put(" error" ," server_error" ) })
244- val httpResp = provider.writeCredentialResponse(origRequest.withIssuer(issuerBase), credResp.response)
261+ if (credResp !is CredentialResponseResult .Success ) {
262+ val failure = credResp as CredentialResponseResult .Failure
263+ val httpResp = provider.writeCredentialError(request, failure.error)
264+ return @post call.respond(HttpStatusCode .fromValue(httpResp.status), httpResp.payload)
265+ }
266+ val httpResp = provider.writeCredentialResponse(request, credResp.response)
245267 call.respond(HttpStatusCode .fromValue(httpResp.status), httpResp.payload)
246268 }
247269 }
@@ -268,7 +290,7 @@ class Wallet2MoreUseCasesTest {
268290
269291 val sdJwtInfra = startIssuer(host, issuerPort1, sdJwtConfig,
270292 CredentialConfiguration (format = VciCredentialFormat .SD_JWT_VC , vct = pidVct,
271- cryptographicBindingMethodsSupported = setOf (CryptographicBindingMethod .Jwk ),
293+ cryptographicBindingMethodsSupported = setOf (CryptographicBindingMethod .Jwk , CryptographicBindingMethod . DidKey ),
272294 proofTypesSupported = mapOf (" jwt" to ProofType (proofSigningAlgValuesSupported = setOf (" ES256" , " EdDSA" )))),
273295 sdJwtCode,
274296 buildJsonObject { put(" given_name" ," Alice" ); put(" family_name" ," Wallet" ); put(" issuing_country" ," AT" ) },
@@ -306,7 +328,7 @@ class Wallet2MoreUseCasesTest {
306328 http.post(" /wallet/$walletId /credentials/receive" ) {
307329 contentType(ContentType .Application .Json )
308330 setBody(ReceiveCredentialRequest (offerJson = Json .encodeToJsonElement(
309- CredentialOffer .withPreAuthorizedCodeGrant(" http:// $host : $issuerPort1 " , listOf (sdJwtConfig), sdJwtCode)
331+ CredentialOffer .withPreAuthorizedCodeGrant(sdJwtInfra.issuerBase , listOf (sdJwtConfig), sdJwtCode)
310332 ).jsonObject))
311333 }.also { assertEquals(HttpStatusCode .OK , it.status, it.bodyAsText()) }
312334 .body<ReceiveCredentialResult >()
@@ -316,7 +338,7 @@ class Wallet2MoreUseCasesTest {
316338 http.post(" /wallet/$walletId /credentials/receive" ) {
317339 contentType(ContentType .Application .Json )
318340 setBody(ReceiveCredentialRequest (offerJson = Json .encodeToJsonElement(
319- CredentialOffer .withPreAuthorizedCodeGrant(" http:// $host : $issuerPort2 " , listOf (jwtConfig), jwtCode)
341+ CredentialOffer .withPreAuthorizedCodeGrant(jwtInfra.issuerBase , listOf (jwtConfig), jwtCode)
320342 ).jsonObject))
321343 }.also { assertEquals(HttpStatusCode .OK , it.status, it.bodyAsText()) }
322344 .body<ReceiveCredentialResult >()
0 commit comments