Skip to content

Commit c4e5442

Browse files
committed
Update OpenID scheme
1 parent c8fbdad commit c4e5442

File tree

15 files changed

+72
-36
lines changed

15 files changed

+72
-36
lines changed

build.gradle.kts

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ plugins {
1414
}
1515

1616
group = "id.walt"
17-
version = "1.13.0-SNAPSHOT8"
17+
version = "1.13.0-SNAPSHOT9"
1818

1919
repositories {
2020
mavenCentral()
@@ -35,8 +35,8 @@ dependencies {
3535
implementation("com.github.multiformats:java-multibase:v1.1.0")
3636
implementation("com.microsoft.azure:azure-keyvault:1.2.6")
3737
implementation("com.microsoft.azure:azure-client-authentication:1.7.14")
38-
implementation("com.nimbusds:nimbus-jose-jwt:9.25.6")
39-
implementation("com.nimbusds:oauth2-oidc-sdk:10.1")
38+
implementation("com.nimbusds:nimbus-jose-jwt:9.30.1")
39+
implementation("com.nimbusds:oauth2-oidc-sdk:10.5.1")
4040

4141
implementation("org.bouncycastle:bcprov-jdk15to18:1.72")
4242
implementation("org.bouncycastle:bcpkix-jdk15to18:1.72")
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

src/main/kotlin/id/walt/cli/OidcCommand.kt

+9-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import id.walt.services.oidc.CompatibilityMode
2626
import id.walt.services.oidc.OIDC4CIService
2727
import id.walt.services.oidc.OIDC4VPService
2828
import id.walt.services.oidc.OIDCUtils
29+
import id.walt.services.oidc.OidcSchemeFixer.unescapeOpenIdScheme
2930
import java.net.URI
3031
import java.util.*
3132

@@ -343,8 +344,8 @@ class OidcVerificationGenUrlCommand :
343344
val client_url: String by option(
344345
"-c",
345346
"--client-url",
346-
help = "Base URL of client, e.g. Wallet, default: openid:///"
347-
).default("openid:///")
347+
help = "Base URL of client, e.g. Wallet, default: openid://"
348+
).default("openid://")
348349
val response_type: String by option("--response-type", help = "Response type, default: vp_token").default("vp_token")
349350
val response_mode: String by option("--response-mode", help = "Response mode, default: fragment").default("fragment")
350351
val nonce: String? by option("-n", "--nonce", help = "Nonce, default: auto-generated")
@@ -358,12 +359,12 @@ class OidcVerificationGenUrlCommand :
358359

359360
override fun run() {
360361
val req = OIDC4VPService.createOIDC4VPRequest(
361-
wallet_url = URI.create(client_url),
362+
wallet_url = client_url,
362363
redirect_uri = URI.create("${verifier_url.trimEnd('/')}/${verifier_path.trimStart('/')}"),
363364
nonce = nonce?.let { Nonce(it) } ?: Nonce(),
364365
response_type = ResponseType.parse(response_type),
365366
response_mode = ResponseMode(response_mode),
366-
scope = Scope(scope),
367+
scope = scope?.let { Scope(scope) },
367368
presentation_definition = if (scope.isNullOrEmpty() && presentationDefinitionUrl.isNullOrEmpty()) {
368369
PresentationDefinition("1",
369370
input_descriptors = credentialTypes?.map { credType ->
@@ -386,17 +387,18 @@ class OidcVerificationGenUrlCommand :
386387
presentation_definition_uri = presentationDefinitionUrl?.let { URI.create(it) },
387388
state = state?.let { State(it) }
388389
)
389-
println("${req.toURI()}")
390+
println("${req.toURI().unescapeOpenIdScheme()}")
390391
}
391392
}
392393

393394
class OidcVerificationParseCommand : CliktCommand(name = "parse", help = "Parse SIOP presentation request") {
394395

395-
val authUrl: String? by option(
396+
val authUrl: String by option(
396397
"-u",
397398
"--url",
398399
help = "Authentication request URL from verifier portal, or get-url / gen-url subcommands"
399-
)
400+
).required()
401+
400402
val listCredentials: Boolean by option(
401403
"-l",
402404
"--list-credentials",

src/main/kotlin/id/walt/credentials/w3c/templates/VcTemplateManager.kt

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ object VcTemplateManager {
4545
when {
4646
File(resource.file).isDirectory ->
4747
File(resource.file).walk().filter { it.isFile }.map { it.nameWithoutExtension }.toList()
48+
4849
else -> {
4950
FileSystems.newFileSystem(resource.toURI(), emptyMap<String, String>()).use { fs ->
5051
Files.walk(fs.getPath("/vc-templates"))

src/main/kotlin/id/walt/model/oidc/VCClaims.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package id.walt.model.oidc
22

33
import com.beust.klaxon.Json
44
import com.nimbusds.openid.connect.sdk.OIDCClaimsRequest
5-
import id.walt.common.ListOrSingleVC
65
import id.walt.common.KlaxonWithConverters
6+
import id.walt.common.ListOrSingleVC
77
import id.walt.credentials.w3c.VerifiablePresentation
88
import id.walt.model.dif.PresentationDefinition
99
import id.walt.model.dif.PresentationSubmission

src/main/kotlin/id/walt/rest/custodian/CustodianController.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package id.walt.rest.custodian
22

3-
import id.walt.common.VCObjectList
43
import id.walt.common.KlaxonWithConverters
4+
import id.walt.common.VCObjectList
55
import id.walt.credentials.w3c.VerifiableCredential
66
import id.walt.credentials.w3c.toVerifiableCredential
77
import id.walt.crypto.Key

src/main/kotlin/id/walt/services/ecosystems/essif/EbsiVa.kt

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import com.beust.klaxon.Json
44
import id.walt.common.SingleVC
55
import id.walt.credentials.w3c.VerifiableCredential
66
import id.walt.credentials.w3c.W3CProof
7-
import kotlinx.serialization.SerialName
8-
import kotlinx.serialization.Serializable
97

108
//@Serializable
119
data class EbsiVAWrapper(

src/main/kotlin/id/walt/services/ecosystems/essif/userwallet/UserWalletService.kt

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ object UserWalletService {
127127
when {
128128
"claim timestamp check failed" in verifiableAuthorization || "JWT has expired" in verifiableAuthorization ->
129129
"Your Verifiable Authorization was stored invalidly. Your EBSI Bearer token at the time of onboarding (getting the Verifiable Authorization) was expired."
130+
130131
else -> "(yet-)Unknown error in Verifiable Authorization. See the error message above for more information."
131132
}
132133
)

src/main/kotlin/id/walt/services/hkvstore/FileSystemHKVStore.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class FileSystemHKVStore(configPath: String) : HKVStoreService() {
4949
storeMappings()
5050
}
5151

52-
private fun retrieveHashMapping(hashMapping: String): String = mappingProperties.value[hashMapping] as? String ?: throw IllegalArgumentException("No HKVS mapping found for hash: $hashMapping")
52+
private fun retrieveHashMapping(hashMapping: String): String = mappingProperties.value[hashMapping] as? String
53+
?: throw IllegalArgumentException("No HKVS mapping found for hash: $hashMapping")
5354

5455
private fun hashIfNeeded(path: Path): File {
5556
if (path.name.length > MAX_KEY_SIZE) {

src/main/kotlin/id/walt/services/oidc/OIDC4CIService.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import com.nimbusds.oauth2.sdk.util.JSONObjectUtils
1515
import com.nimbusds.openid.connect.sdk.*
1616
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata
1717
import id.walt.common.KlaxonWithConverters
18-
import id.walt.common.KlaxonWithConverters
1918
import id.walt.credentials.w3c.VerifiableCredential
2019
import id.walt.crypto.LdSignatureType
2120
import id.walt.model.oidc.*
@@ -148,10 +147,11 @@ object OIDC4CIService {
148147
@Suppress("UNCHECKED_CAST")
149148
val supportedCredentials = issuer.oidc_provider_metadata.customParameters["credentials_supported"]
150149

151-
when (supportedCredentials ){
150+
when (supportedCredentials) {
152151
null -> {
153152
return emptyMap()
154153
}
154+
155155
is net.minidev.json.JSONObject -> {
156156
return (issuer.oidc_provider_metadata.customParameters["credentials_supported"]?.let {
157157
log.debug { "OIDC Provider \"${issuer.id}\" metadata - credentials supported: " + it.toString() }
@@ -163,9 +163,11 @@ object OIDC4CIService {
163163

164164
}?.filterValues { v -> v != null } as Map<String, CredentialMetadata>?) ?: mapOf()
165165
}
166+
166167
is Map<*, *> -> {
167168
return supportedCredentials.filter { it.value != null } as? Map<String, CredentialMetadata> ?: mapOf()
168169
}
170+
169171
else -> return emptyMap()
170172
}
171173
}

src/main/kotlin/id/walt/services/oidc/OIDC4VPService.kt

+11-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import id.walt.model.oidc.OIDCProvider
2020
import id.walt.model.oidc.SIOPv2Response
2121
import id.walt.model.oidc.SelfIssuedIDToken
2222
import id.walt.model.oidc.VpTokenRef
23+
import id.walt.services.oidc.OidcSchemeFixer.safeOpenidScheme
2324
import io.javalin.http.Context
2425
import mu.KotlinLogging
2526
import java.net.URI
@@ -43,7 +44,7 @@ object OIDC4VPService {
4344
}
4445

4546
fun createOIDC4VPRequest(
46-
wallet_url: URI,
47+
wallet_url: String,
4748
redirect_uri: URI,
4849
nonce: Nonce,
4950
response_type: ResponseType = ResponseType("vp_token"),
@@ -77,8 +78,9 @@ object OIDC4VPService {
7778
customParams[presentationDefinitionKey] = listOf(presentationDefinitionValue)
7879
}
7980
customParameters?.let { customParams.putAll(customParameters) }
81+
8082
return AuthorizationRequest(
81-
wallet_url,
83+
wallet_url.safeOpenidScheme(),
8284
response_type,
8385
response_mode,
8486
ClientID(redirect_uri.toString()),
@@ -124,7 +126,7 @@ object OIDC4VPService {
124126
private fun authRequest2OIDC4VPRequest(authReq: AuthorizationRequest): AuthorizationRequest {
125127
val customParameters = authReq.customParameters.toMutableMap()
126128
return createOIDC4VPRequest(
127-
authReq.requestURI ?: URI.create("openid:///"),
129+
authReq.requestURI?.toString() ?: OidcSchemeFixer.openIdSchemeFix,
128130
redirect_uri = authReq.requestObject?.jwtClaimsSet?.claims?.get("redirect_uri")?.let { URI.create(it.toString()) }
129131
?: authReq.redirectionURI,
130132
nonce = (authReq.requestObject?.jwtClaimsSet?.claims?.get("nonce")
@@ -147,10 +149,14 @@ object OIDC4VPService {
147149
}
148150
// 3
149151
?: (authReq.requestObject?.jwtClaimsSet?.getJSONObjectClaim("claims")
150-
?.get("id_token") as? LinkedTreeMap<*, *>)?.let { idToken ->
152+
?.get("id_token") as? LinkedTreeMap<*, *>)?.let { idToken ->
151153
(idToken["vp_token"] as? LinkedTreeMap<*, *>)?.let { vpToken ->
152154
(vpToken["presentation_definition"] as? LinkedTreeMap<*, *>)?.let { presDef ->
153-
KlaxonWithConverters().parse<PresentationDefinition>(KlaxonWithConverters().toJsonString(presDef))
155+
KlaxonWithConverters().parse<PresentationDefinition>(
156+
KlaxonWithConverters().toJsonString(
157+
presDef
158+
)
159+
)
154160
}
155161
}
156162
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package id.walt.services.oidc
2+
3+
import java.net.URI
4+
5+
/**
6+
* These hacks are required as you can't call
7+
* URI.create("openid://")
8+
*/
9+
object OidcSchemeFixer {
10+
11+
val schemeReplacement = "waltid-authentication-request-uri-hack"
12+
13+
val openIdSchemeFix = "openid://$schemeReplacement"
14+
val openIdSchemeFixUri: URI = URI.create(openIdSchemeFix)
15+
val openidInitiateIssuanceSchemeFix = "openid-initiate-issuance://$schemeReplacement"
16+
val openidInitiateIssuanceSchemeFixUri: URI = URI.create(openidInitiateIssuanceSchemeFix)
17+
18+
fun String.safeOpenidScheme(): URI = URI.create(if (this == "openid://") openIdSchemeFix else this)
19+
fun String.safeOpenidInitiateIssuanceScheme(): URI =
20+
URI.create(if (this == "openid-initiate-issuance://") openidInitiateIssuanceSchemeFix else this)
21+
22+
fun String.unescapeOpenIdScheme() = this.replace(schemeReplacement, "")
23+
fun URI.unescapeOpenIdScheme(): URI = URI.create(this.toString().unescapeOpenIdScheme())
24+
}

src/main/kotlin/id/walt/signatory/Signatory.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ class WaltIdSignatory(configurationPath: String) : Signatory() {
200200
}
201201

202202
override fun removeTemplate(templateId: String) {
203-
val template = VcTemplateManager.getTemplate(templateId,true, configuration.templatesFolder)
203+
val template = VcTemplateManager.getTemplate(templateId, true, configuration.templatesFolder)
204204
if (template.mutable) {
205205
VcTemplateManager.unregisterTemplate(templateId)
206206
} else {

src/test/kotlin/id/walt/cli/EssifCommandTest.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class EssifCommandTest : StringSpec({
137137
}
138138
}
139139

140-
"6. Get timestamp transaction hash".config(enabled = enableTests) {
140+
"6. Get timestamp transaction hash".config(enabled = false) {
141141
timestamp =
142142
WaltIdTimestampService().getByTransactionHash(transactionHash!!)
143143
validateTimestamp(timestamp)
@@ -152,7 +152,7 @@ class EssifCommandTest : StringSpec({
152152
)
153153
}
154154

155-
"7. Get by timestamp Id".config(enabled = enableTests) {
155+
"7. Get by timestamp Id".config(enabled = false) {
156156
val timestampReceived =
157157
WaltIdTimestampService().getByTimestampId(timestamp!!.timestampId!!)
158158
validateTimestamp(timestampReceived)

src/test/kotlin/id/walt/services/oidc/OIDC4VCTest.kt

+11-10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import id.walt.model.oidc.*
1818
import id.walt.servicematrix.ServiceMatrix
1919
import id.walt.services.did.DidService
2020
import id.walt.services.jwt.JwtService
21+
import id.walt.services.oidc.OidcSchemeFixer.unescapeOpenIdScheme
2122
import id.walt.signatory.ProofConfig
2223
import id.walt.signatory.ProofType
2324
import id.walt.signatory.Signatory
@@ -44,13 +45,13 @@ class OIDC4VCTest : AnnotationSpec() {
4445
lateinit var SUBJECT_DID: String
4546

4647
val FULL_AUTH_INITIATION_REQUEST: URI = URI.create(
47-
"openid-initiate-issuance:/?" +
48+
"openid-initiate-issuance://waltid-openid-scheme-hack?" +
4849
"issuer=http%3A%2F%2Flocalhost%3A$TEST_ISSUER_PORT" +
4950
"&credential_type=${OIDCTestProvider.TEST_CREDENTIAL_ID}" +
5051
"&op_state=${OIDCTestProvider.TEST_OP_STATE}"
5152
)
5253
val PRE_AUTH_INITIATION_REQUEST: URI = URI.create(
53-
"openid-initiate-issuance:/?" +
54+
"openid-initiate-issuance://waltid-openid-scheme-hack?" +
5455
"issuer=http%3A%2F%2Flocalhost%3A$TEST_ISSUER_PORT" +
5556
"&credential_type=${OIDCTestProvider.TEST_CREDENTIAL_ID}" +
5657
"&pre-authorized_code=${OIDCTestProvider.TEST_PREAUTHZ_CODE}"
@@ -186,7 +187,7 @@ class OIDC4VCTest : AnnotationSpec() {
186187
val presentation = Custodian.getService().createPresentation(listOf(credential), SUBJECT_DID)
187188
.toVerifiablePresentation()
188189
val req = OIDC4VPService.createOIDC4VPRequest(
189-
URI("openid:///"),
190+
"openid://",
190191
redirect_uri = URI.create("${testProvider.url}/present"),
191192
nonce = Nonce(),
192193
presentation_definition = OIDCTestProvider.TEST_PRESENTATION_DEFINITION
@@ -210,7 +211,7 @@ class OIDC4VCTest : AnnotationSpec() {
210211
val presentation = Custodian.getService().createPresentation(listOf(credential), SUBJECT_DID)
211212
.toVerifiablePresentation()
212213
val req = OIDC4VPService.createOIDC4VPRequest(
213-
URI.create("openid:///"),
214+
"openid://",
214215
redirect_uri = URI.create("${testProvider.url}/present"),
215216
nonce = Nonce(),
216217
presentation_definition = OIDCTestProvider.TEST_PRESENTATION_DEFINITION
@@ -233,7 +234,7 @@ class OIDC4VCTest : AnnotationSpec() {
233234
val presentation = Custodian.getService().createPresentation(listOf(credential), SUBJECT_DID)
234235
.toVerifiablePresentation()
235236
val req = OIDC4VPService.createOIDC4VPRequest(
236-
URI.create("openid:///"),
237+
"openid://",
237238
redirect_uri = URI.create("${testProvider.url}/present"),
238239
nonce = Nonce(),
239240
presentation_definition = OIDCTestProvider.TEST_PRESENTATION_DEFINITION
@@ -262,7 +263,7 @@ class OIDC4VCTest : AnnotationSpec() {
262263
val presentation = Custodian.getService().createPresentation(listOf(credential), SUBJECT_DID)
263264
.toVerifiablePresentation()
264265
val req = OIDC4VPService.createOIDC4VPRequest(
265-
URI.create("openid:///"),
266+
"openid://",
266267
redirect_uri = URI.create("${testProvider.url}/present"),
267268
nonce = Nonce(),
268269
presentation_definition = OIDCTestProvider.TEST_PRESENTATION_DEFINITION
@@ -423,16 +424,16 @@ class OIDC4VCTest : AnnotationSpec() {
423424

424425
@Test
425426
fun testPresentationDefinitionByReference() {
426-
val req = OIDC4VPService.createOIDC4VPRequest(
427-
URI.create("openid:///"),
427+
val reqURI = OIDC4VPService.createOIDC4VPRequest(
428+
"openid://",
428429
URI.create("/"),
429430
Nonce(),
430431
presentation_definition_uri = URI.create("${testProvider.url}/pdByReference")
431-
)
432+
).toURI().unescapeOpenIdScheme()
432433

433434
// parse request
434435
val parsedReq = shouldNotThrowAny {
435-
OIDC4VPService.parseOIDC4VPRequestUri(req.toURI())
436+
OIDC4VPService.parseOIDC4VPRequestUri(reqURI)
436437
}
437438

438439
parsedReq.customParameters shouldContainKey "presentation_definition_uri"

0 commit comments

Comments
 (0)