Skip to content
This repository has been archived by the owner on Nov 20, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2 from walt-id/feat-ebsi-compliance
Browse files Browse the repository at this point in the history
Feat ebsi compliance
  • Loading branch information
severinstampler authored Oct 10, 2023
2 parents 5cc3574 + 8966076 commit f11785d
Show file tree
Hide file tree
Showing 29 changed files with 891 additions and 212 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,35 @@ For the full demo verifier implementation, refer to `/src/jvmTest/kotlin/id/walt
## License

Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-xyzkit/blob/master/LICENSE)


# Example flows:

## EBSI conformance test: Credential issuance:

```mermaid
sequenceDiagram
Issuer -->> Wallet: Issuance request (QR, or by request)
Wallet ->> Issuer: Resolve credential offer
Issuer -->> Wallet: Credential offer
Wallet ->> Issuer: fetch OpenID Credential Issuer metadata
Issuer -->> Wallet: Credential issuer metadata
Wallet ->> Wallet: Check if external authorization service (AS)
Wallet ->> AS: fetch OpenID provider metadata
AS -->> Wallet: OpenID provider metadata
Wallet ->> Wallet: resolve offered credential metainfo
Wallet ->> Wallet: Generate code verifier and code challenge
Wallet ->> AS: Authorization request, auth details and code challenge
AS -->> Wallet: Redirect to wallet with id_token request
Wallet ->> Wallet: Generate id_token
Wallet ->> AS: POST id_token response to redirect_uri
AS -->> Wallet: Redirect to wallet with authorzation code
Wallet ->> AS: POST token request with code and code verifier
AS -->> Wallet: Respond with access_token and c_nonce
loop Fetch offered credentials
Wallet ->> Wallet: generate DID proof
Wallet ->> Issuer: Fetch credentials from credential endpoint or batch-credential endpoint, with DID proof
Issuer -->> Wallet: Credential (and updated c_nonce)
end
```
7 changes: 4 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ kotlin {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("io.ktor:ktor-http:$ktor_version")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.1")
implementation("id.walt:waltid-sd-jwt:1.2309211114.0")
implementation("id.walt:waltid-sd-jwt:1.2310101347.0")
}
}
val commonTest by getting {
Expand All @@ -98,7 +98,7 @@ kotlin {
implementation("io.kotest:kotest-assertions-json:5.7.2")

implementation("id.walt.servicematrix:WaltID-ServiceMatrix:1.1.3")
implementation("id.walt:waltid-ssikit:1.JWTPRESENT")
implementation("id.walt:waltid-ssikit:1.JWTTYP")
implementation("id.walt:core-crypto:1.0.2-SNAPSHOT")

implementation("io.ktor:ktor-server-core-jvm:$ktor_version")
Expand All @@ -107,7 +107,8 @@ kotlin {
implementation("io.ktor:ktor-server-default-headers-jvm:$ktor_version")
implementation("io.ktor:ktor-server-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-client-core:$ktor_version")
implementation("io.ktor:ktor-client-cio:$ktor_version")
//implementation("io.ktor:ktor-client-cio:$ktor_version")
implementation("io.ktor:ktor-client-java:$ktor_version")
implementation("io.ktor:ktor-client-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
implementation("io.ktor:ktor-client-logging-jvm:$ktor_version")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ data class AuthorizationDetails(
@SerialName("doctype") val docType: String? = null,
@Serializable(ClaimDescriptorNamespacedMapSerializer::class) val claims: Map<String, Map<String, ClaimDescriptor>>? = null,
@SerialName("credential_definition") val credentialDefinition: JsonLDCredentialDefinition? = null,
val locations: List<String>? = null,
override val customParameters: Map<String, JsonElement> = mapOf()
) : JsonDataObject() {
override fun toJSON() = Json.encodeToJsonElement(AuthorizationDetailsSerializer, this).jsonObject
Expand All @@ -42,11 +43,11 @@ data class AuthorizationDetails(
override fun fromJSON(jsonObject: JsonObject): AuthorizationDetails =
Json.decodeFromJsonElement(AuthorizationDetailsSerializer, jsonObject)

fun fromOfferedCredential(offeredCredential: OfferedCredential) = AuthorizationDetails(
fun fromOfferedCredential(offeredCredential: OfferedCredential, issuerLocation: String? = null) = AuthorizationDetails(
OPENID_CREDENTIAL_AUTHORIZATION_TYPE,
offeredCredential.format, offeredCredential.types, null,
offeredCredential.docType, null,
offeredCredential.credentialDefinition, offeredCredential.customParameters
offeredCredential.credentialDefinition, issuerLocation?.let { listOf(it) }, offeredCredential.customParameters
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ enum class CredentialFormat(val value: String) {
mso_mdoc("mso_mdoc"),
jwt_vp_json("jwt_vp_json"),
jwt_vp_json_ld("jwt_vp_json-ld"),
ldp_vp("ldp_vp");
ldp_vp("ldp_vp"),
jwt_vc("jwt_vc"),
jwt_vp("jwt_vp");

companion object {
fun fromValue(value: String): CredentialFormat? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ data class OpenIDProviderMetadata(
@SerialName("authorization_server") val authorizationServer: String? = null,
@SerialName("display") @Serializable(DisplayPropertiesListSerializer::class) val display: List<DisplayProperties>? = null,
@SerialName("presentation_definition_uri_supported") val presentationDefinitionUriSupported: Boolean? = null,
@SerialName("vp_formats_supported") @Serializable(SupportedVPFormatMapSerializer::class) val vpFormatsSupported: Map<CredentialFormat, SupportedVPFormat>? = null,
//@SerialName("vp_formats_supported") @Serializable(SupportedVPFormatMapSerializer::class) val vpFormatsSupported: Map<CredentialFormat, SupportedVPFormat>? = null,
@SerialName("client_id_schemes_supported") val clientIdSchemesSupported: List<String>? = null,
override val customParameters: Map<String, JsonElement> = mapOf()
) : JsonDataObject() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package id.walt.oid4vc.errors

import id.walt.oid4vc.requests.AuthorizationRequest
import id.walt.oid4vc.requests.IAuthorizationRequest
import id.walt.oid4vc.responses.AuthorizationCodeResponse
import id.walt.oid4vc.responses.AuthorizationErrorCode
import id.walt.oid4vc.responses.PushedAuthorizationResponse

class AuthorizationError(
val authorizationRequest: AuthorizationRequest,
val authorizationRequest: IAuthorizationRequest,
val errorCode: AuthorizationErrorCode,
override val message: String? = null
) : Exception() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package id.walt.oid4vc.errors

import id.walt.oid4vc.requests.CredentialOfferRequest
import id.walt.oid4vc.requests.TokenRequest
import id.walt.oid4vc.responses.TokenErrorCode

class CredentialOfferError(
val credentialOfferRequest: CredentialOfferRequest, val errorCode: CredentialOfferErrorCode, override val message: String? = null
): Exception() {
}

enum class CredentialOfferErrorCode {
invalid_request,
invalid_issuer
}
17 changes: 17 additions & 0 deletions src/commonMain/kotlin/id/walt/oid4vc/interfaces/IHttpClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package id.walt.oid4vc.interfaces

import io.ktor.http.*
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject

data class SimpleHttpResponse (
val status: HttpStatusCode,
val headers: Headers,
val body: String?
)
interface IHttpClient {
fun httpGet(url: Url, headers: Headers? = null): SimpleHttpResponse
fun httpPostObject(url: Url, jsonObject: JsonObject, headers: Headers? = null): SimpleHttpResponse
fun httpSubmitForm(url: Url, formParameters: Parameters, headers: Headers? = null): SimpleHttpResponse
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package id.walt.oid4vc.providers

data class SIOPProviderConfig(
data class CredentialWalletConfig(
val redirectUri: String? = null
) : OpenIDProviderConfig()
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ package id.walt.oid4vc.providers
data class OpenIDClientConfig(
val clientID: String,
val clientSecret: String?,
val redirectUri: String?
val redirectUri: String?,
val useCodeChallenge: Boolean = false
)
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,24 @@ abstract class OpenIDCredentialIssuer(

return url
}

/**
* Returns the URI on which the credential offer object can be retrieved for this issuance session, if the request object is passed by reference.
* The returned URI will be used for the credential_offer_uri parameter of the credential offer request.
* Override, to use custom path, by default, the path will be: "$baseUrl/credential_offer/<session_id>, e.g.: "https://issuer.myhost.com/api/credential_offer/1234-4567-8900"
* @param issuanceSession The issuance session for which the credential offer uri is created
*/
open protected fun getCredentialOfferByReferenceUri(issuanceSession: IssuanceSession): String {
return URLBuilder(baseUrl).appendPathSegments("credential_offer", issuanceSession.id).buildString()
}

open fun getCredentialOfferRequest(
issuanceSession: IssuanceSession, byReference: Boolean = false
): CredentialOfferRequest {
return if(byReference) {
CredentialOfferRequest(null, getCredentialOfferByReferenceUri(issuanceSession))
} else {
CredentialOfferRequest(issuanceSession.credentialOffer)
}
}
}
Loading

0 comments on commit f11785d

Please sign in to comment.