a-sit-plus / vck

Kotlin Multiplatform library implementing W3C VC Data Model and ISO 18013-5 mDL
https://a-sit-plus.github.io/vck/
Apache License 2.0
17 stars 1 forks source link
eudi-wallet iso-18013-5 koltin kotlin-multiplatform mdl openid4vc openid4vci openid4vp sd-jwt ssi verifiable-credentials wallet
VC-K – Verifiable Credentials Library for Kotlin Multiplatform # VC-K – Verifiable Credentials Library for Kotlin Multiplatform [![A-SIT Plus Official](https://img.shields.io/badge/A--SIT_Plus-official-005b79?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNDMuNzYyODYgMTg0LjgxOTk5Ij48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiIGNsaXBQYXRoVW5pdHM9InVzZXJTcGFjZU9uVXNlIj48cGF0aCBkPSJNMCA1OTUuMjhoODQxLjg5VjBIMFoiLz48L2NsaXBQYXRoPjwvZGVmcz48ZyBjbGlwLXBhdGg9InVybCgjYSkiIHRyYW5zZm9ybT0ibWF0cml4KDEuMzMzMzMzMyAwIDAgLTEuMzMzMzMzMyAtNDgyLjI1IDUxNy41MykiPjxwYXRoIGZpbGw9IiMwMDViNzkiIGQ9Ik00MTUuNjcgMjQ5LjUzYy03LjE1LjA4LTEzLjk0IDEtMjAuMTcgMi43NWE1Mi4zMyA1Mi4zMyAwIDAgMC0xNy40OCA4LjQ2IDQwLjQzIDQwLjQzIDAgMCAwLTExLjk2IDE0LjU2Yy0yLjY4IDUuNDEtNC4xNCAxMS44NC00LjM1IDE5LjA5bC0uMDIgNi4xMnYyLjE3YS43MS43MSAwIDAgMCAuNy43M2gxNi41MmMuMzkgMCAuNy0uMzIuNzEtLjdsLjAxLTIuMmMwLTIuNi4wMi01LjgyLjAzLTYuMDcuMi00LjYgMS4yNC04LjY2IDMuMDgtMTIuMDZhMjguNTIgMjguNTIgMCAwIDEgOC4yMy05LjU4IDM1LjI1IDM1LjI1IDAgMCAxIDExLjk2LTUuNTggNTUuMzggNTUuMzggMCAwIDEgMTIuNTgtMS43NmM0LjMyLjEgOC42LjcgMTIuNzQgMS44YTM1LjA3IDM1LjA3IDAgMCAxIDExLjk2IDUuNTcgMjguNTQgMjguNTQgMCAwIDEgOC4yNCA5LjU3YzEuOTYgMy42NCAzIDguMDIgMy4xMiAxMy4wMnYyNC4wOUgzNjIuNGEuNy43IDAgMCAwLS43MS43VjMzNWMwIDguNDMuMDEgOC4wNS4wMSA4LjE0LjIgNy4zIDEuNjcgMTMuNzcgNC4zNiAxOS4yMmE0MC40MyA0MC40MyAwIDAgMCAxMS45NiAxNC41N2M1IDMuNzYgMTAuODcgNi42MSAxNy40OCA4LjQ2YTc3LjUgNzcuNSAwIDAgMCAyMC4wMiAyLjc3YzcuMTUtLjA3IDEzLjk0LTEgMjAuMTctMi43NGE1Mi4zIDUyLjMgMCAwIDAgMTcuNDgtOC40NiA0MC40IDQwLjQgMCAwIDAgMTEuOTUtMTQuNTdjMS42Mi0zLjI2IDMuNzctMTAuMDQgMy43Ny0xNC42OCAwLS4zOC0uMTctLjc0LS41NC0uODJsLTE2Ljg5LS40Yy0uMi0uMDQtLjM0LjM0LS4zNC41NCAwIC4yNy0uMDMuNC0uMDYuNi0uNSAyLjgyLTEuMzggNS40LTIuNjEgNy42OWEyOC41MyAyOC41MyAwIDAgMS04LjI0IDkuNTggMzUuMDEgMzUuMDEgMCAwIDEtMTEuOTYgNS41NyA1NS4yNSA1NS4yNSAwIDAgMS0xMi41NyAxLjc3Yy00LjMyLS4xLTguNjEtLjcxLTEyLjc1LTEuOGEzNS4wNSAzNS4wNSAwIDAgMS0xMS45Ni01LjU3IDI4LjUyIDI4LjUyIDAgMCAxLTguMjMtOS41OGMtMS44Ni0zLjQ0LTIuOS03LjU1LTMuMDktMTIuMmwtLjAxLTcuNDdoODkuMTZhLjcuNyAwIDAgMCAuNy0uNzJ2LTM5LjVjLS4xLTcuNjUtMS41OC0xNC40LTQuMzgtMjAuMDZhNDAuNCA0MC40IDAgMCAwLTExLjk1LTE0LjU2IDUyLjM3IDUyLjM3IDAgMCAwLTE3LjQ4LTguNDcgNzcuNTYgNzcuNTYgMCAwIDAtMjAuMDEtMi43N1oiLz48cGF0aCBmaWxsPSIjY2U0OTJlIiBkPSJNNDE5LjM4IDI4MC42M2gtNy41N2EuNy43IDAgMCAwLS43MS43MXYxNS40MmE4LjE3IDguMTcgMCAwIDAtMy43OCA2LjkgOC4yOCA4LjI4IDAgMCAwIDE2LjU0IDAgOC4yOSA4LjI5IDAgMCAwLTMuNzYtNi45di0xNS40MmEuNy43IDAgMCAwLS43Mi0uNzEiLz48L2c%2BPC9zdmc%2B&logoColor=white&labelColor=white)](https://a-sit-plus.github.io) [![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-brightgreen.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0) [![Kotlin](https://img.shields.io/badge/kotlin-multiplatform--mobile-orange.svg?logo=kotlin)](http://kotlinlang.org) [![Kotlin](https://img.shields.io/badge/kotlin-2.0.0-blue.svg?logo=kotlin)](http://kotlinlang.org) [![Java](https://img.shields.io/badge/java-17-blue.svg?logo=OPENJDK)](https://www.oracle.com/java/technologies/downloads/#java17) [![Maven Central](https://img.shields.io/maven-central/v/at.asitplus.wallet/vck)](https://mvnrepository.com/artifact/at.asitplus.wallet/vck)

This library implements verifiable credentials to support several use cases, i.e. issuing of credentials, presentation of credentials and validation thereof. This library may be shared between backend services issuing credentials, wallet apps holding credentials, and verifier apps validating them.

Credentials may be represented in the W3C VC Data Model or as ISO credentials according to ISO/IEC 18013-5:2021. Issuing may happen according to ARIES RFC 0453 Issue Credential V2 or with OpenID for Verifiable Credential Issuance. Presentation of credentials may happen according to ARIES RFC 0454 Present Proof V2 or with Self-Issued OpenID Provider v2, supporting OpenID for Verifiable Presentations.

Architecture

This library was built with Kotlin Multiplatform and Multiplatform Mobile in mind. Its primary targets are JVM, Android and iOS. In order to achieve smooth usage especially under iOS, there have been some notable design decisions:

Notable features for multiplatform are:

Some parts for increased multiplatform support have been extracted into separate repositories:

The main entry point for applications is an instance of HolderAgent, VerifierAgent or IssuerAgent, according to the nomenclature from the W3C VC Data Model.

Many classes define several constructor parameters, some of them with default values, to enable a simple form of dependency injection. Implementers are advised to specify the parameter names of arguments passed to increase readability and prepare for future extensions.

Aries

A single run of an ARIES protocol (for issuing or presentation) is implemented by the *Protocol classes, whereas the *Messenger classes should be used by applications to manage several runs of a protocol. These classes reside in the artifact vck-aries.

OpenId

For SIOPv2 see OidcSiopProtocol, and for OpenId4VCI see WalletService. Most code resides in the artifact/subdirectory vck-openid. Both protocols are able to transport credentials as plain JWTs, SD-JWT or ISO 18013-5.

Limitations

iOS Implementation

The DefaultCryptoService for iOS should not be used in production as it does not implement encryption, decryption, key agreement and message digests correctly. See the Swift Package for details on a more correct iOS implementation.

Credentials

A single credential itself is an instance of CredentialSubject (when using the plain JWT representation with ECDSA signatures) and has no special meaning attached to it. This library implements AtomicAttribute2023 as a trivial sample of a custom credential. For Selective Disclosure JWT and ISO representations, only the claims (holding names and values) exist, without any data class holding the values.

Other libraries using this library may call LibraryInitializer.registerExtensionLibrary() to register that extension with this library. See our implementation of the EU PID credential or our implementation of the Mobile Driving Licence for examples. We also maintain a comprehensive list of all credentials powered by this library over here.

Dataflow for OID4VCI

We'll present an issuing process according to OID4VCI, along with OID4VP, with all terms taken from there.

The credential issuer serves the following metadata:

{
  "issuer": "https://wallet.a-sit.at/credential-issuer",
  "credential_issuer": "https://wallet.a-sit.at/credential-issuer",
  "authorization_servers": [
    "https://wallet.a-sit.at/authorization-server"
  ],
  "credential_endpoint": "https://wallet.a-sit.at/credential-issuer/credential",
  "token_endpoint": "https://wallet.a-sit.at/authorization-server/token",
  "authorization_endpoint": "https://wallet.a-sit.at/authorization-server/authorize",
  "credential_identifiers_supported": true,
  "credential_configurations_supported": {
    "at.a-sit.wallet.atomic-attribute-2023": {
      "format": "mso_mdoc",
      "scope": "at.a-sit.wallet.atomic-attribute-2023",
      "cryptographic_binding_methods_supported": [
        "cose_key"
      ],
      "credential_signing_alg_values_supported": [
        "ES256"
      ],
      "doctype": "at.a-sit.wallet.atomic-attribute-2023.iso",
      "claims": {
        "at.a-sit.wallet.atomic-attribute-2023": {
          "given_name": {},
          "family_name": {},
          "date_of_birth": {}
        }
      }
    },
    "AtomicAttribute2023#jwt_vc_json": {
      "format": "jwt_vc_json",
      "scope": "AtomicAttribute2023",
      "cryptographic_binding_methods_supported": [
        "did:key",
        "urn:ietf:params:oauth:jwk-thumbprint"
      ],
      "credential_signing_alg_values_supported": [
        "ES256"
      ],
      "credential_definition": {
        "type": [
          "VerifiableCredential",
          "AtomicAttribute2023"
        ],
        "credentialSubject": {
          "given_name": {},
          "family_name": {},
          "date_of_birth": {}
        }
      }
    },
    "AtomicAttribute2023#vc+sd-jwt": {
      "format": "vc+sd-jwt",
      "scope": "AtomicAttribute2023",
      "cryptographic_binding_methods_supported": [
        "did:key",
        "urn:ietf:params:oauth:jwk-thumbprint"
      ],
      "credential_signing_alg_values_supported": [
        "ES256"
      ],
      "vct": "AtomicAttribute2023",
      "claims": {
        "given_name": {},
        "family_name": {},
        "date_of_birth": {}
      }
    }
  }
}

The credential issuer starts with a credential offer:

{
  "credential_issuer": "https://wallet.a-sit.at/credential-issuer",
  "credential_configuration_ids": [
    "at.a-sit.wallet.atomic-attribute-2023",
    "AtomicAttribute2023#jwt_vc_json",
    "AtomicAttribute2023#vc+sd-jwt"
  ],
  "grants": {
    "authorization_code": {
      "issuer_state": "18136181-97fd-4af9-9e66-85a51cdea269",
      "authorization_server": "https://wallet.a-sit.at/authorization-server"
    },
    "urn:ietf:params:oauth:grant-type:pre-authorized_code": {
      "pre-authorized_code": "2c74a00b-70b8-4062-9757-75652174bc5d",
      "authorization_server": "https://wallet.a-sit.at/authorization-server"
    }
  }
}

Since the issuer gives an pre-authorized code, the wallet uses this for the token request:

{
  "grant_type": "urn:ietf:params:oauth:grant-type:pre-authorized_code",
  "redirect_uri": "https://wallet.a-sit.at/app/callback",
  "client_id": "https://wallet.a-sit.at/app",
  "authorization_details": [
    {
      "type": "openid_credential",
      "format": "vc+sd-jwt",
      "vct": "AtomicAttribute2023"
    }
  ],
  "pre-authorized_code": "2c74a00b-70b8-4062-9757-75652174bc5d"
}

The credential issuer answers with an access token:

{
  "access_token": "413ed326-107b-4429-8efa-872cb89949d8",
  "token_type": "bearer",
  "expires_in": 3600,
  "c_nonce": "4fc81553-970e-4765-899f-611d7c4173ae",
  "authorization_details": []
}

The wallet creates a credential request, including a proof-of-posession of its private key:

{
  "format": "vc+sd-jwt",
  "vct": "AtomicAttribute2023",
  "proof": {
    "proof_type": "jwt",
    "jwt": "eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiS1R2WlRpX28xeTc5REQwSk1IanZyYUpkaXFEWGpNZlZIZVNYemVEVVV4ZyIsInkiOiJiUkZReC1meG9GOURJOTdUWmRQZmNYUXlEY0V0eEQydlNTNWNZMERHYXJZIn19.eyJpc3MiOiJodHRwczovL3dhbGxldC5hLXNpdC5hdC9hcHAiLCJhdWQiOiJodHRwczovL3dhbGxldC5hLXNpdC5hdC9jcmVkZW50aWFsLWlzc3VlciIsIm5vbmNlIjoiNGZjODE1NTMtOTcwZS00NzY1LTg5OWYtNjExZDdjNDE3M2FlIiwiaWF0IjoxNzIwNDIyNTM3fQ.FNM1BCli6pHEXedxRGOmNzxfpsEwQz67onbeQZfRU4tNxEqYauW45MrFkrYsi0Ly7wvfdoPkONZG7s7EmD-vkA"
  }
}

The JWT included decodes to the following:

{
  "typ": "openid4vci-proof+jwt",
  "alg": "ES256",
  "jwk": {
    "crv": "P-256",
    "kty": "EC",
    "x": "KTvZTi_o1y79DD0JMHjvraJdiqDXjMfVHeSXzeDUUxg",
    "y": "bRFQx-fxoF9DI97TZdPfcXQyDcEtxD2vSS5cY0DGarY"
  }
}
.
{
  "iss": "https://wallet.a-sit.at/app",
  "aud": "https://wallet.a-sit.at/credential-issuer",
  "nonce": "4fc81553-970e-4765-899f-611d7c4173ae",
  "iat": 1720422537
}

The credential issuer issues the following credential:

{
  "format": "vc+sd-jwt",
  "credential": "eyJraWQiOiJkaWQ6a2V5OnpEbmFleVlrcDlqZ0hjN3lheEcybkZTMXc4MXJISkVyS3hZSkVtTExVRTJVU05wWmUiLCJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJkaWQ6a2V5OnpEbmFlVEN2aDdZS1N5b21hUnFONFZ3TnZSZFRLdzJBakVkR0VkcndtNHZEUXU5RXciLCJuYmYiOjE3MjA0MjI1MzcsImlzcyI6ImRpZDprZXk6ekRuYWV5WWtwOWpnSGM3eWF4RzJuRlMxdzgxckhKRXJLeFlKRW1MTFVFMlVTTnBaZSIsImV4cCI6MTcyMDQyMjU5NywiaWF0IjoxNzIwNDIyNTM3LCJqdGkiOiJ1cm46dXVpZDpkODE1ZTEwZC1hNDRkLTQxNDQtYmZhNS05Zjk5MTNjZjE5ZmUiLCJfc2QiOlsiaHBNUTFpeWV0cTkzeWVCNG5FZXVmeDYweHY0WTVqbHFWcThIc2tJc1pZMCIsIkFHR1hZRTlIeXF1bGxTSF9iTC02dkRTSEhyZU9HckRWUVVOdEVQM3p1QlEiLCJva2VaSElRQkNQVlVxdUo4VmI3bHd2bWtLWnNmUktKVUE3X0VOMlZjX2M0Il0sInZjdCI6IkF0b21pY0F0dHJpYnV0ZTIwMjMiLCJzdGF0dXMiOnsiaWQiOiJodHRwczovL3dhbGxldC5hLXNpdC5hdC9iYWNrZW5kL2NyZWRlbnRpYWxzL3N0YXR1cy8xIzMiLCJ0eXBlIjoiUmV2b2NhdGlvbkxpc3QyMDIwU3RhdHVzIiwicmV2b2NhdGlvbkxpc3RJbmRleCI6MywicmV2b2NhdGlvbkxpc3RDcmVkZW50aWFsIjoiaHR0cHM6Ly93YWxsZXQuYS1zaXQuYXQvYmFja2VuZC9jcmVkZW50aWFscy9zdGF0dXMvMSJ9LCJfc2RfYWxnIjoic2hhLTI1NiIsImNuZiI6eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwia2lkIjoidXJuOmlldGY6cGFyYW1zOm9hdXRoOmp3ay10aHVtYnByaW50OnNoYTI1NjpaaC1yNlZsWE5UQUZheTVYVjFzWFpJUG5mZjdHcGVZMFAzTHNPVDJmSFlRPSIsIngiOiJLVHZaVGlfbzF5NzlERDBKTUhqdnJhSmRpcURYak1mVkhlU1h6ZURVVXhnIiwieSI6ImJSRlF4LWZ4b0Y5REk5N1RaZFBmY1hReURjRXR4RDJ2U1M1Y1kwREdhclkifX0.oDdilbVBmoRpy162gcDR8a0vvYHlP7LXvJ3gxmjz4dYKRLhoMwM_tIcu0Dy5_ftXPq5IO1p9GYMkfUhHk881kw~WyI4cWRNYkN6SWZGajQxT1ZVUE13OEI5R2xaN2tiemxxaXg5T1RSU2huWGgwIiwiZ2l2ZW5fbmFtZSIsIkVyaWthIl0~WyIxUDdYQjB5eFFjaVBlZkVrV2o5R2N0MzNUYVZXeGNnVER1N19aTGptWG13IiwiZmFtaWx5X25hbWUiLCJNdXN0ZXJmcmF1Il0~WyJ3a2VlWG4wejAwa2tiaHVaeVBXM2dwZVBpOXhSVWU1cmVrQ3Npc2d6ZXg4Iiwic3ViamVjdCIsInN1YmplY3QiXQ"
}

The SD-JWT included decodes to the following:

{
  "kid": "did:key:zDnaeyYkp9jgHc7yaxG2nFS1w81rHJErKxYJEmLLUE2USNpZe",
  "typ": "vc+sd-jwt",
  "alg": "ES256"
}
.
{
  "sub": "did:key:zDnaeTCvh7YKSyomaRqN4VwNvRdTKw2AjEdGEdrwm4vDQu9Ew",
  "nbf": 1720422537,
  "iss": "did:key:zDnaeyYkp9jgHc7yaxG2nFS1w81rHJErKxYJEmLLUE2USNpZe",
  "exp": 1720422597,
  "iat": 1720422537,
  "jti": "urn:uuid:d815e10d-a44d-4144-bfa5-9f9913cf19fe",
  "_sd": [
    "hpMQ1iyetq93yeB4nEeufx60xv4Y5jlqVq8HskIsZY0",
    "AGGXYE9HyqullSH_bL-6vDSHHreOGrDVQUNtEP3zuBQ",
    "okeZHIQBCPVUquJ8Vb7lwvmkKZsfRKJUA7_EN2Vc_c4"
  ],
  "vct": "AtomicAttribute2023",
  "status": {
    "id": "https://wallet.a-sit.at/backend/credentials/status/1#3",
    "type": "RevocationList2020Status",
    "revocationListIndex": 3,
    "revocationListCredential": "https://wallet.a-sit.at/backend/credentials/status/1"
  },
  "_sd_alg": "sha-256",
  "cnf": {
    "crv": "P-256",
    "kty": "EC",
    "kid": "urn:ietf:params:oauth:jwk-thumbprint:sha256:Zh-r6VlXNTAFay5XV1sXZIPnff7GpeY0P3LsOT2fHYQ=",
    "x": "KTvZTi_o1y79DD0JMHjvraJdiqDXjMfVHeSXzeDUUxg",
    "y": "bRFQx-fxoF9DI97TZdPfcXQyDcEtxD2vSS5cY0DGarY"
  }
}

with the following claims appended:

["8qdMbCzIfFj41OVUPMw8B9GlZ7kbzlqix9OTRShnXh0","given_name","Erika"]
["1P7XB0yxQciPefEkWj9Gct33TaVWxcgTDu7_ZLjmXmw","family_name","Musterfrau"]
["wkeeXn0z00kkbhuZyPW3gpePi9xRUe5rekCsisgzex8","date_of_birth","1980-01-13"]

Dataflow for SIOPv2

We'll present a presentation process according to SIOPv2, along with OID4VP, with all terms taken from there.

The verifier creates a URL to be displayet to the wallet, containing a reference to the authentication request itself:

https://wallet.a-sit.at/mobile
    ?client_id=https://example.com/rp
    &request_uri=https://example.com/request/15a4e87c-8e3e-4368-87a3-48083bac7232

The authentication request is signed as a JWS and contains the following header and payload:

{
  "alg": "ES256",
  "x5c": [
    "MIIBNDCB2qADAgECAgjm7Gfdm0IFUDAKBggqhkjOPQQDAjASMRAwDgYDVQQDDAdEZWZhdWx0MB4XDTI0MDcxNzEzNTUzMVoXDTI0MDcxNzEzNTYwMVowEjEQMA4GA1UEAwwHRGVmYXVsdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCaD9zTN05m6zZSX+QrQzdF4l1Bt3pVSo6VV9VFUSFCkImDkSsyCbgkJoZFkUNObbMiZbccQk6H33HAfxGWpLTyjGjAYMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29tMAoGCCqGSM49BAMCA0kAMEYCIQDSotU4YnsO0Ar5+barXkCn3PQlCaPJEnBwRL60SnHW9wIhAK5mLYgfslZvT5jFmMrS3Ivzm2EpNyjdCPGVT3wpt6/t"
  ]
}
.
{
  "response_type": "id_token vp_token",
  "client_id": "example.com",
  "scope": "openid profile AtomicAttribute2023 AtomicAttribute2023 at.a-sit.wallet.atomic-attribute-2023",
  "state": "36efe035-ecf6-4c56-94c8-3dfe167ddaad",
  "nonce": "148279b8-5222-4db9-bb9b-0614bbe0ef7d",
  "client_metadata": {
    "redirect_uris": [
      "https://example.com/rp"
    ],
    "jwks": {
      "keys": [
        {
          "crv": "P-256",
          "kty": "EC",
          "x": "JoP3NM3TmbrNlJf5CtDN0XiXUG3elVKjpVX1UVRIUKQ",
          "y": "ImDkSsyCbgkJoZFkUNObbMiZbccQk6H33HAfxGWpLTw"
        }
      ]
    },
    "subject_syntax_types_supported": [
      "urn:ietf:params:oauth:jwk-thumbprint",
      "did:key"
    ],
    "vp_formats": {
      "jwt_vp": {
        "alg": [ "ES256", "ES384", "ES512" ]
      },
      "vc+sd-jwt": {
        "alg": [ "ES256", "ES384", "ES512" ]
      },
      "mso_mdoc": {
        "alg": [ "ES256", "ES384", "ES512" ]
      }
    }
  },
  "id_token_type": "subject_signed_id_token",
  "presentation_definition": {
    "id": "b0611eea-89e4-4b78-8f44-40a2cb608d4a",
    "input_descriptors": [
      {
        "id": "9a5511bf-efe4-4ec2-84e5-4cabf1d13000",
        "schema": [
          {
            "uri": "https://wallet.a-sit.at/schemas/1.0.0/AtomicAttribute2023.json"
          }
        ],
        "constraints": {
          "fields": [
            {
              "path": [ "$[\"family_name\"]" ]
            },
            {
              "path": [ "$[\"given_name\"]" ]
            },
            {
              "path": [ "$.vct" ],
              "filter": {
                "type": "string",
                "pattern": "AtomicAttribute2023"
              }
            }
          ]
        }
      }
    ],
    "format": {
      "vc+sd-jwt": {
        "alg": [ "ES256", "ES384", "ES512" ]
      }
    }
  },
  "client_id_scheme": "x509_san_dns",
  "response_mode": "direct_post",
  "response_uri": "https://example.com/response",
  "aud": "https://example.com/rp",
  "iss": "https://example.com/rp"
}

The certificate includes the X.509 SAN extension with the value example.com.

The wallet posts back the response to https://example.com/response with the parameters presentation_submission, vp_token and state.

The value for presentation_submission is:

{
  "id": "be3972bc-18cf-4e24-abf4-fe49eb870bab",
  "definition_id": "b0611eea-89e4-4b78-8f44-40a2cb608d4a",
  "descriptor_map": [
    {
      "id": "9a5511bf-efe4-4ec2-84e5-4cabf1d13000",
      "format": "vc+sd-jwt",
      "path": "$"
    }
  ]
}

The value for vp_token is an SD-JWT, with header and payload:

{
  "kid": "did:key:zDnaezoC5xdfzSdKoCZCZiw52eqnTks3xMKMDRTFKfSiq9obD",
  "typ": "vc+sd-jwt",
  "alg": "ES256"
}
.
{
  "sub": "did:key:zDnaexYu9PCJsDmg7YwyBCJR2qQT8DxqwXhm4BLAJVWUgW1Ms",
  "nbf": 1721224531,
  "iss": "did:key:zDnaezoC5xdfzSdKoCZCZiw52eqnTks3xMKMDRTFKfSiq9obD",
  "exp": 1721224591,
  "iat": 1721224531,
  "jti": "urn:uuid:6ed95e4f-83ca-457c-8d8b-bf8bf93ad09e",
  "_sd": [
    "0nIEwdknjG7aMeKKiVnJNd7lK-dleq0_RPYc84gDg98",
    "DZo-dZ4EQTxcekJqJKvhYZySgxodgH1vvT5su__pJlk"
  ],
  "vct": "AtomicAttribute2023",
  "status": {
    "id": "https://wallet.a-sit.at/backend/credentials/status/1#2",
    "type": "RevocationList2020Status",
    "revocationListIndex": 2,
    "revocationListCredential": "https://wallet.a-sit.at/backend/credentials/status/1"
  },
  "_sd_alg": "sha-256",
  "cnf": {
    "crv": "P-256",
    "kty": "EC",
    "x": "3Tyi-VLN7pmm6kcbRuyD0bYrYllX_cH1fYbf72pNwtI",
    "y": "6K5c5nYUfRBY3vRo-Q043hr8cFCqYj3iwnxwGFF2Ca8"
  }
}

with the following claims appended:

["_bBdCtzFzC1DYL1r6gNq2fZPMvMdR31mo2zp6gq1sZ4","given_name","Susanne"]
["SNDcrxkCBGQrLj0kHiX72Gn4l5dz-sfKo12tbqAoNf8","family_name","Meier"]
["wkeeXn0z00kkbhuZyPW3gpePi9xRUe5rekCsisgzex8","date_of_birth","1990-02-14"]

as well as a key binding (the JWT is decoded):

{
  "typ": "kb+jwt",
  "alg": "ES256",
  "jwk": {
    "crv": "P-256",
    "kty": "EC",
    "x": "3Tyi-VLN7pmm6kcbRuyD0bYrYllX_cH1fYbf72pNwtI",
    "y": "6K5c5nYUfRBY3vRo-Q043hr8cFCqYj3iwnxwGFF2Ca8"
  }
}
.
{
  "iat": 1721224531,
  "aud": "did:key:zDnaeT2KFSXyCSo3WLjrZeQsNwaCQv2r6bV4bLZNbdhZKhBbh",
  "nonce": "148279b8-5222-4db9-bb9b-0614bbe0ef7d",
  "sd_hash": "UkLqyUz3zKR1iMTam7AsP89aEzYvbQqiJ4jfV82A96c"
}

Contributing

External contributions are greatly appreciated! Be sure to observe the contribution guidelines (see CONTRIBUTING.md). In particular, external contributions to this project are subject to the A-SIT Plus Contributor License Agreement (see also CONTRIBUTING.md).



This project has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement No 959072.

EU flag

The Apache License does not apply to the logos, (including the A-SIT logo) and the project/module name(s), as these are the sole property of A-SIT/A-SIT Plus GmbH and may not be used in derivative works without explicit permission!