Skip to content

PID Option B: Authenticated Channel with eID Card

Basic Idea

This flow describes a flow that issues PID credentials in ISO mdoc / SD-JWT VC format on-demand when the presentation request is received. It uses the OpenID4VCI protocol for issuance and the OpenID4VP protocol for presentation. The PID credentials are HMAC'd by the PID Provider for the specific transaction.

The Wallet Instance is not trusted for the management of the keys, hence majority of the signing is performed by the PID Provider.

Lifecycle

The credential is created on-demand by the PID Provider, i.e., a new credential is created for every transaction. The credential is not stored in the wallet. It is bound to the specific transaction through not only the nonce and audience, but also the symmetric key used for HMAC'ing, which is derived from ephemeral keys of the RP and PID Provider.

Credential formats

Two solutions are described:

  • ISO mdoc: The ISO mdoc credential format is used with:
  • issuerAuth as issuer data authentication, a COSE_Sign1 signature over the MobileSecurityObject (see ISO 23220-4 7.1.3.4.2.1) signed by the PID Provider
    • no signed hashes are transmitted, i.e., digestAlgorithm and valueDigests are omitted
  • deviceMAC as mdoc authentication method, a COSE_Mac0 MAC over the deviceAuthentication data (see ISO 18013-5 9.1.3.5) signed by the PID Provider
    • containing the PID data
  • SD-JWT VC: The SD-JWT VC credential format is used with:
  • SD-JWT issued by the PID Provider, a JOSE JWS with MAC key derived from ECDH* and signed by the PID Provider
    • containing the hashes of PID data
    • the Wallet provides an ephemeral, asymmetric key to the PID Provider for the key binding
  • KB-JWT issued by the Wallet, a JOSE JWS using digital signature and signed by the Wallet
    • containing nonce and audience of the Relying Party
    • containing a hash of the SD-JWT and the selected disclosures
  • the Disclosures
    • containing the PID data

The establishment of the authenticated channel is defined: - for mdoc, in Chapter 9.1.3.5 in ISO 18013-5, in the mdoc MAC Authentication section - for SD-JWT, the IETF Draft for Designated Verifier Signatures defines a JOSE algorithm to be used

Cryptographic Formats

Long-Term keys:

  • PID Provider has long-term key pair \((pp\_pub, pp\_priv)\) is used to sign over the ephemeral issuer key, authenticating it for credential issuance
  • Relying Party has long-term key pair \((rp\_pub, rp\_priv)\) which is used to sign over the authorization request, authenticating its contents
  • Wallet Instance has long-term device bound key pair \((device\_pub, device\_priv)\) which is used to generate proof of possession of wallet attestation

Transaction-specific keys:

  • Relying Party generates ephemeral key pair \((rp\_eph\_pub, rp\_eph\_priv)\) which is used as contribution to HMAC key
  • PID Provider generates ephemeral key pair \((pp\_eph\_pub, pp\_eph\_priv)\) which is used as contribution to HMAC key
  • Wallet generates ephemeral key pair \((kb\_eph\_pub, kb\_eph\_priv)\) which is used to sign KB-JWT (SD-JWT)

Artifacts mdoc:

  • PID Provider creates issuerAuth: \(\text{issuerAuth} := \text{sign}(pp\_eph\_pub, x5chain)_{pp\_priv}\)
  • Key for authenticating mdoc: \(hmac\_key := \text{ecdh}(rp\_eph\_pub, pp\_eph\_priv)\)
  • PID Provider creates deviceAuth: \(\text{deviceAuth} := \text{hmac}(\mathit{eID\_data}, \mathit{SessionTranscript})_{hmac\_key}\)

Artifacts SD-JWT VC:

  • PID Provider creates certificate for ephemeral issuer key: \(x5c\_header := \text{sign}(pp\_eph\_pub)_{pp\_priv}\)
  • Key for authenticating SD-JWT: \(hmac\_key := \text{ecdh}(rp\_eph\_pub, pp\_eph\_priv)\)
  • PID Provider creates SD-JWT: \(sd\_jwt := \text{hmac}(x5c\_header, \mathit{eID\_data}, kb\_eph\_pub)_{hmac\_key}\)
  • Wallet creates KB-JWT: \(kb\_jwt := \text{sign}(nonce, audience, \text{hash}(sd\_jwt, disclosures))_{kb\_eph\_priv}\)

Dependencies

TODO: May want to expand to include metadata.

For mdoc:

G cluster_pid_provider PID Provider cluster_rp Relying Party pp 🗝 (pp_priv, pp_pub) pp_eph 🗝 (pp_eph_priv, pp_eph_pub) pp->pp_eph sign (issuerAuth) shared_secret_k 🗝 shared secret K pp_eph->shared_secret_k ecdh-ka deviceAuth deviceAuth(eID data, SessionTranscript(nonce, audience)) sd_jwt_hmac_key 🗝 hmac key shared_secret_k->sd_jwt_hmac_key key derivation sd_jwt_hmac_key->deviceAuth hmac rp 🗝 (rp_priv, rp_pub) rp_eph 🗝 (rp_eph_priv, rp_eph_pub) rp->rp_eph sign (Auth. Request) rp_eph->shared_secret_k ecdh-ka

For SD-JWT VC:

G cluster_pid_provider PID Provider cluster_rp Relying Party cluster_wallet Wallet pp 🗝 (pp_priv, pp_pub) pp_eph 🗝 (pp_eph_priv, pp_eph_pub) pp->pp_eph sign shared_secret_k 🗝 shared secret K pp_eph->shared_secret_k ecdh-ka user_data eID data sd_jwt_hmac_key 🗝 hmac key shared_secret_k->sd_jwt_hmac_key key derivation sd_jwt_hmac_key->user_data hmac (SD-JWT) kb_eph 🗝 (kb_eph_priv, kb_eph_pub) sd_jwt_hmac_key->kb_eph hmac (SD-JWT) nonce_audience nonce, audience kb_eph->nonce_audience sign (KB-JWT) rp 🗝 (rp_priv, rp_pub) rp_eph 🗝 (rp_eph_priv, rp_eph_pub) rp->rp_eph sign (Auth. Request) rp_eph->shared_secret_k ecdh-ka

Sequence Diagram

User Journey: PID Presentation - Authenticated Channel - eID Card

PID presentation over OpenID4VP and On-the-fly PID Issuance over OpenID4VCI with SD-JWTPID presentation over OpenID4VP and On-the-fly PID Issuance over OpenID4VCI with SD-JWTUserOpenID HolderUserOpenID HolderBrowser App(same device)Browser App(same device)Relying PartyLong-term Key: (rp_pub,rp_priv)Relying PartyLong-term Key: (rp_pub,rp_priv)User's EUDI Wallet Instance(eID-Client)User's EUDI Wallet Instance(eID-Client)PID Provider(eService+eID Server)Long-term Key: (pp_pub,pp_priv)PID Provider(eService+eID Server)Long-term Key: (pp_pub,pp_priv)(001)browse to applicationScreen: same_device_relying_party_start(002)[TLS] HTTP GET <rp-website>(003)generate ephemeral key pair(rp_eph_pub, rp_eph_priv)every RP in the ecosystem must alwaysinclude ephemeral key in client metadata forECDH-KA for MAC, however we need theephemeral key anyway for encryption(004)create OpenID4VPAuthorization Request, sign with rp_priv, store under <request_uri>Authorization Request includes:- presentation_definition- purpose- state- nonce- rp_eph_pub with PoP bound to client_id- response_uri(005)generate new browser sessionsession_id and bind theauthorization request to it(006)[TLS] HTTP 200 HTMLcontaining wallet-linkopenid4vp://authorize?")client_id=..&request_uri=<request_uri>Set-Cookie: sid=session_id(007)action to start flow/launchwallet(008)launch with wallet-linkopenid4vp://Potential security risk: Wallet app may bespoofed by malicious appScreen: launch_wallet(009)unlock walletmay be moved to later point in flow orremoved, see notes.Screen: unlock_wallet(010)[TLS] HTTP GET<request_uri>Potential privacy risk: RP learns existence ofwallet app and potentially identifyinginformation (e.g., headers)(011)[TLS] HTTP 200 <JWT-SecuredAuthorization Request>(012)validate AuthorizationRequest JWT using rp_pub(013)user consent to present PID toRelying Party for givenpurposeScreen: consent_present_credentialPID provisioningPID Issuer and EUDI Wallet have inherenttrust relationship, metadata may bepre-configured or retrieved(014)Wallet fetches fresh walletattestation from backend(015)[TLS] HTTP POST</session_endpoint> walletattestation nonce(016)generate and store nonce(017)[TLS] HTTP 200 <walletattestation nonce>(018)sign wallet attestation PoPJWT (incl. wallet attestationnonce) with device_priv(019)[TLS] HTTP POST PAR (PKCEcode_challenge, walletattestation JWT, walletattestation PoP JWT,redirect_uri,authorization_details=PIDwith requested attributes)(020)verify wallet attestation & PoPcheck Wallet Provider solutionstatus on trust list(021)[TLS] HTTP 200 request_uriAttestation guarantees with high certaintythat Wallet is trustworthy and notmanipulated(022)[TLS] HTTP GET <OpenID4VCIAuthorizationRequest(request_uri)>Screen: eid_startRead eID or Smart eID acc. to BSI TR-03130(023)[TLS] HTTP 200 starting theeID Process(024)eID Process(025)<eID-PIN>Screen: eid_pin(026)eID Process(027)[TLS] HTTP GET finishing theeID process with refreshUrlScreen: eid_nfc_data(028)[TLS] HTTP 200 AuthorizationResponse (code)(029)[TLS] HTTP POST TokenRequest(code, code_verifier,DPoP key)(030)match code and verifycode_verifier(031)[TLS] HTTP 200 TokenResponse(access_token,c_nonce)(032)generate credential responseencryption key pair(cre_eph_pub, cre_eph_priv)(033)createcredential_response_encryptionobject with jwk containingcre_eph_pubalt[B.1.1: ISO mdoc](034)calculate SessionTranscript(mDocGeneratedNonce,client_id, responseUri, nonce)(035)[TLS] Credential Request(rp_eph_pub,credential_response_encryptionobject, SessionTranscript)-rp_eph_pub is sent in `verifier_pub`parameter-SessionTranscript is sent in`session_transcript` parameter-no `proof`/`proofs` parameters(036)generate device key pair(pp_eph_pub, pp_eph_priv), create issuerAuth withpp_eph_pub and w/o dataitems and sign with pp_priv[B.1.2: SD-JWT VC](037)generate ephemeral key pairfor KB-JWT (kb_eph_pub,kb_eph_priv) and signc_nonce(038)[TLS] Credential Request(rp_eph_pub,credential_response_encryptionobject, kb_eph_pub)rp_eph_pub is sent in `verifier_pub`parameter(039)generate issuer key pair(pp_eph_pub, pp_eph_priv), create certificate for chainwith pp_eph_pub as x5cheader and sign with pp_priv(040)perform DH key exchangewith rp_eph_pub andpp_eph_priv / pp_eph_priv, generate shared secret kand derive MAC key for PIDECDH-MAC not specified for JOSE yetSD-JWT is HMAC'd, not signedalt[B.1.1: ISO mdoc](041)create deviceAuth using MACkey with eID data andSessionTranscript(042)generate encrypted credentialresponse JWT using the valuesreceived in thecredential_response_encryptionobject(043)[TLS] HTTP 200JWT(CredentialResponse(mdoc))(044)decrypt credential responseJWT and retrieve PID[B.1.2: SD-JWT VC](045)- create SD-JWT with eID data,include kb_eph_pub and x5cwith pp_eph_pub, HMAC usingMAC key(046)generate encrypted credentialresponse JWT using the valuesreceived in thecredential_response_encryptionobject(047)[TLS] HTTP 200JWT(CredentialResponse(SD-JWT))SD-JWT contains no disclosuresand no KB-JWT(048)decrypt credential responseJWT and retrieve PID(049)create KB-JWT payload withnonce, audience, and hash ofSD-JWT and selecteddisclosures and sign withkb_eph_priv(050)create vp_token andpresentation_submission(051)add mDL presentationaccording to<presentation_definition>with <nonce> to vp_tokenand presentation_submissionWallet may add presentations with keysunder its own control as thecommunication channel between Relying Partand PID Provider is not E2EE(052)[TLS] HTTP POST encrypted<AuthorizationResponse(presentation_submission,vp_token, state)>(053)look up state in existingsessionscreate & store response_codefor session(054)[TLS] HTTP 200 <redirect_uriincl. response_code>(055)launch browser with<redirect_uri withresponse_code>Screen: success_redirect(056)[TLS] HTTP GET <redirect_uriwith response_code>Cookie: sid=session_id(057)look up session withsession_id and matchresponse_code(058)perform DH key exchangewith rp_eph_priv from sessionand pp_eph_pub, generate shared secret k derive MAC keyalt[B.1.1: ISO mdoc](059)verify contents of<vp_token>:- verify mdocissuerAuth/deviceAuth PIDwith MAC key- calculate and validatecorrect SessionTranscript[B.1.2: SD-JWT VC](060)verify contents of<vp_token>:- verify SD-JWT PID with MACkey- verify KB-JWT withkb_eph_pub from SD-JWT- validate nonce and audiencefrom KB-JWT(061)[TLS] HTTP 200 <HTML withcontinued UX flow>Screen: same_device_relying_party_identified

Sequence Diagram

Wallet Activation

To initialize the wallet, the Wallet obtains wallet attestation as defined in Wallet Attestation.

On-demand PID Issuance

Note: While certain assumptions about session management of the Relaying Party are made here, the concrete implementation is considered out of scope for this document. The usual security considerations for web session management apply.

  1. User browses to Relying Party (RP) website
  2. Browser app on the user's device opens the RP website
  3. RP generates a key pair to be used for ECDH key agreement for SD-JWT HMAC'ing
  4. RP generates an OpenID4VP Authorization Request and stores it under a request_uri (e.g., https://rp.example.com/oidc/request/1234);
  5. The request is bound to the user's browser session
  6. It is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id
  7. It contains the ephemeral key for ECDH key agreement for SD-JWT HMAC'ing
  8. It contains RP's nonce and state
  9. It contains the RP's response_uri endpoint for sending the Authorization Response over POST
  10. RP generates a new browser session and binds the generated Authorization Request to it
  11. RP returns an HTML page to the browser containing a link to the wallet app (e.g., openid4vp://authorize?client_id=..&request_uri=https://rp.example.com/oidc/request/1234); a cookie with the browser session id is set
  12. The user clicks on the link
  13. The RP website navigates to the custom scheme link to launch the wallet app
  14. The user unlocks the wallet app (see notes below)
  15. The wallet app retrieves the Authorization Request from the RP website (e.g., https://rp.example.com/oidc/request/1234)
  16. The wallet app receives the Authorization Request
  17. The wallet app validates the Authorization Request using the RP's public key
    • Was the signature valid and the key bound to the RP's metadata?
    • Security: This ensures that the Authorization Request was not tampered with; it does not ensure that the party that sent the Authorization Request is the RP.
  18. The Wallet displays information about the identity of the Relying Party and the purpose, the user gives consent to present the PID.
  19. The Wallet fetches fresh wallet attestation from the Wallet Provider backend.
  20. The Wallet requests a fresh nonce for the wallet attestation nonce from the PID Provider (wallet attestation nonce).
  21. The PID Provider generates a fresh nonce linked to the issuance session.
  22. The PID Provider returns the wallet attestation nonce to the Wallet.
  23. The Wallet generates a Wallet Attestation PoP and signs it with device_priv; containing
    • audience
    • expiration time
    • wallet attestation nonce
  24. The wallet sends the Pushed Authorization Request to the PID Provider; containing
    • PKCE code_challenge
    • wallet attestation + PoP
    • redirect_uri
    • an authorization_details object requesting a PID with a list of claims
  25. The PID Provider verifies the wallet attestation and its proof of possession and validates the certification status of the Wallet Solution on a trust list.
  26. The PID Provider returns a request_uri that is bound to the Pushed Authorization Request.
  27. The Wallet sends the Authorization Request; containing
    • the PAR request_uri
  28. The PID Provider responds with the first step to start the eID process with the wallet app, e.g. the tcToken. Note that this is the direct HTTP Response to Step 14.
  29. Further communication is exchanged to perform the eID process
  30. The user provides the eID PIN to the wallet app.
  31. Further communication is exchanged to perform the eID process
  32. The eID process is finished and as a final step the Wallet sends a request to the PID Provider calling the refreshURL. From now on Wallet and PID Provider are using the TLS-PSK channel generated by the eID flow.
  33. The PID Provider responds to the Wallet with an Authorization Response; containing
    • the auth code
  34. The Wallet sends a Token Request to the PID Provider; containing:
    • the auth code from Authorization Response
    • the PKCE code_verifier matching the code_challenge from Authorization Request
    • a DPoP key
  35. The PID Provider matches the code and verifies the PKCE code_verifier to the previously received code_challenge. It then generates an access token bound to the DPoP key.
  36. The PID Provider sends a Token Response; containing
    • DPoP-bound access token
    • a c_nonce
  37. The Wallet generates a new ephemeral keypair (cre_eph_pub, cre_eph_priv).
  38. The Wallet creates the credential_response_encryption JSON object containing the following information:
    • a jwk containing the cre_eph_pub
    • the JWE alg parameter
    • the JWE enc parameter
  39. (mdoc) The Wallet calculates the SessionTranscript according to ISO-18013-7 Annex B.4.4 from mDocGeneratedNonce, client_id, responseUri, nonce. The final result is a SHA-256 hash, thus not revealing the client_id and ResponseUri to the PID Provider.
  40. (mdoc) The Wallet send a Credential Request; containing
    • sessionTranscript
    • the ephemeral RP key rp_eph_pub from the RP's Authorization Request
    • the credential_response_encryption object
    • it does not contain a "proof"
  41. (mdoc) The PID Provider generate an ephemeral DeviceKey pair (pp_eph_pub,pp_eph_priv) and creates the mdoc issuerAuth (MSO) with the public part of DeviceKey and without the IssuerSignedItems and signs it with pp_priv.
  42. (SD-JWT) The Wallet generates an ephemeral key pair for the KB-JWT (kb_eph_pub, kb_eph_priv) and signs the nonce
  43. (SD-JWT) The wallet app sends the Credential Request to the PID Provider; containing
    • the ephemeral RP key rp_eph_pub from the RP's authorization request,
    • the credential_response_encryption object
    • the ephemeral KB-JWT key kb_eph_pub
  44. (SD-JWT) The PID Provider generates the ephemeral issuer key pair (pp_eph_pub, pp_eph_priv) and creates a certificate for the chain with pp_eph_pub as x5c header and signs it with pp_priv.
  45. The PID Provider performs DH key exchange with the ephemeral RP public key rp_eph_pub and the ephemeral issuer private key pp_eph_priv, generates a shared secret k and derives a MAC key for the PID.
  46. (mdoc) The PID Provider creates the mdoc deviceAuth (using the MAC key) containing
    • the user claims
    • the OpenID4VP SessionTranscript(mdocGeneratedNonce, client_id, responseUri, nonce)
  47. (mdoc) The PID Provider creates an encrypted JWT (JWE) using the values received in the credential_response_encryption object and adds (among others) the PID credential to the payload.
  48. (mdoc) The PID Provider sends the Credential Response JWT; containing:
    • PID as mdoc
  49. (mdoc) The Wallet decrypts the Credential Response JWT using the cre_eph_priv and retrieves the PID.
  50. (SD-JWT) The PID Provider creates the issuer-signed part of the SD-JWT (using the MAC key) containing
    • eID as the user claims
    • kb_eph_pub as cnf claim
  51. (SD-JWT) The PID Provider creates an encrypted JWT (JWE) using the values received in the credential_response_encryption object and adds (among others) the PID credential to the payload.
  52. (SD-JWT) The PID Provider sends the Credential Response JWT; containing:
    • PID as SD-JWT VC
  53. (SD-JWT) The Wallet decrypts the Credential Response JWT using the cre_eph_priv and retrieves the PID.
  54. (SD-JWT) The Wallet creates the header and payload for the KB-JWT from audience, nonce, and the hash of SD-JWT and selected disclosures and signs it with its generated kb_eph_priv. The Wallet appends the KB-JWT to the SD-JWT.
  55. The wallet app creates a VP token and a presentation submission from the received SD-JWT PID.
  56. Optional: The wallet app can add further presentations with keys under its own control as the communication channel between Relying Part and PID Provider is not E2EE
  57. The wallet app sends the VP token and presentation submission to the RP (encrypted to the RP's public key rp_eph_pub).
  58. The RP finds a session with the state and generates a response_code for this session
  59. The RP returns the redirect_uri with the response_code to the wallet app
  60. The wallet app launches the browser with the redirect_uri and response_code.
  61. The browser sends the redirect_uri and response code to the RP, attaching the browser session id as a cookie.
  62. The RP looks up whether there exists a session with the session id from the cookie and a matching response_code
  63. Using the data from the session the RP performs DH key exchange with the PID Provider's public key, generates a shared secret k and derives a MAC key.
  64. (mdoc) The RP verifies the PID in the VP token with the MAC key and verifies the SessionTranscript calculated from nonce, mDocGeneratedNonce, client_id, response_uri.
  65. (SD-JWT) The RP verifies the SD-JWT PID in the VP token with the MAC key, verifies the KB-JWT using the kb_eph_pub in the SD-JWT, and verifies the nonce and audience in the KB-JWT
  66. The RP considers the user to be identified in the session context and continues the UX flow.

Extensions to the Protocols

This section defines extentions to the protocols required to implement this flow (Option B).

In this document, the term RP has been used, but this since this section is an extension to an OpenID4VCI protocol, a term from that specification is being used, which is verifier.

Issuer Session Endpoint (at the PID Provider)

Note that this extension is the same across multiple flows.

This endpoint is used by the Wallet to obtain session_id from the PID Provider that is used to bind PoPs to the session and prove their freshness. Support for this endpoint is REQUIRED.

To fetch the session_id, the Wallet MUST send an HTTP request using the POST method and the application/json media type. The PID Provider MUST return the HTTP Status Code 200 and a session_id parameter defined below.

  • session_id: REQUIRED. String that is a unique session identifier, chosen as a cryptographically random nonce with at least 128 bits of entropy.

Communication with the Session Endpoint MUST utilize TLS.

Below is a non-normative example of a request to a Session Endpoint:

POST /session_endpoint HTTP/1.1
Host: server.example.com
Content-Type: application/json

Below is a non-normative example of a response from a Session Endpoint:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
  "session_id": "iOiJSUzI1NiIsInR"
}

OpenID4VCI Credential Issuer Metadata

Note that this extension is the same across multiple flows.

This document defines the following additional Credential Issuer Metadata parameters:

  • session_endpoint: REQUIRED. URL of the Credential Issuer's Session Endpoint, as defined in a previous section. This URL MUST use the https scheme and MAY contain port, path, and query parameter components.

OpenID4VCI Credential Request and Response for PID Issuance in mdoc Credential Format using Authenticated Channel

Note that this section is the same as in Option B'.

Credential Format identifier is mso_mdoc_authenticated_channel.

The following parameters are defined in addition to those defined for the Credential Format mso_mdoc in Annex A.2 of OpenId4VCI: * session_transcript: REQUIRED. String that is a base64url encoded SessionTranscriptBytes as defined in Section 9.1.5.1 of ISO 18013-5. * verifier_pub: REQUIRED. A JSON object as defined in Section 2 of RFC7591. It contains the ephemeral RP key rp_eph_pub from the RP's Authorization Request.

proof or proofs parameter MUST NOT be present.

credential_response_encryption parameter MUST be present. Note: The wallet can find out about the supported cryptographic algorithms by using the Issuer's metadata parameter credential_response_encryption.

DPoP-bound Access token MUST be present.

Below is a non-normative example of a Credential Request during the PID issuance in ISO mso Credential Format over Authenticated Channel:

POST /credential HTTP/1.1
Host: server.example.com
Content-Type: application/json
Authorization: DPoP czZCaGRSa3F0MzpnWDFmQmF0M2JW
DPoP: ey…

{
  "format": "mso_mdoc_authenticated_channel",
  "doctype": "org.iso.18013.5.1.mDL",
  "session_transcript": "...",
  "verifier_pub": {
    "kty": "EC",
    "crv": "P-256",
    "x": "aPPK-...2-Drn",
    "y": "FqJqG...ksKHp"
  },
  "credential_response_encryption": {
    "jwk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "1SptQyCUQiQD3dBcVHTclxRtcqhZlF1rIKcBR-i_WK4",
      "y": "8ayoQrh52zNuRQx8Q0gpmCpOjzbH397mOsaSi8X10c4"
    },
    "alg": "ECDH-ES",
    "enc": "A256GCM"
  }
}

credential parameter in the Credential Response MUST contain a base64url-encoded Document which contains IssuerSigned and the DeviceSigned parameters defined in section 8.3.2.1.2.2 of 18013-5.

The Device key included in the IssuerSigned and used to secure DeviceSigned is generated by the PID Provider, and not by the Wallet as defined in ISO 18013-5.

SessionTranscript used by the PID Provider when calculating DeviceSigned is calculated by the Wallet. Therefore, there is no need for the PID Provider to know the specific values of mdocGeneratedNonce, client_id, responseUri, and nonce parameters used for SessionTranscript calculation by the Wallet. Moreover, there is also no way for the PID Provider to reconstruct these values, as the SessionTranscript is hashed and contains random values chosen by the wallet (i.e. mdocGeneratedNonce).

Below is a non-normative example of a Credential Response JWT (JWE) during the PID issuance in mso Credential Format over Authenticated Channel:

HTTP/1.1 200 OK
Content-Type: application/jwt
Cache-Control: no-store

{
  "epk": {
    "kty": "EC",
    "crv": "P-256",
    "x": "VJUVl-ZqLKzzncZ4Gs_nJfcqY_YBHPkGVN0sRSlF-3s",
    "y": "y4maAWKte676d0wL6um-8wAUJ9pW-mlc528BFeiXn2Y"
  },
  "enc": "A256GCM",
  "alg": "ECDH-ES"
}..
nLuW9PwrGl76pjTy.
nH_XE2LJ2u-N0o8M-tanqoYhJr7hbjo.
3uNrPqJazT9ZSf54sk1Ueg

The decrypted payload of the Credential Response JWT example results in the following structure:

{
  "credential": "..."
}

OpenID4VCI Credential Request and Response for PID Issuance in SD-JWT Credential Format using Authenticated Channel

Note that this section is the same as in Option B.

The following parameter is defined in addition to those defined for the Credential Format vc+sd-jwt in Annex A.3 of OpenId4VCI: * verifier_pub: REQUIRED. A JSON object as defined in Section 2 of RFC7591. It contains the ephemeral RP key rp_eph_pub from the RP's Authorization Request.

New Credential Format identifier is not defined PID Issuance in SD-JWT Credential Format using Authenticated Channel, because the issued Credential in the Credential Response is SD-JWT, which is the same as the one defined in Annex A.3 of OpenId4VCI. Since during PID Issuance in SD-JWT Credential Format using Authenticated Channel, not just IssuerSigned, but also DeviceSigned is returned in the Credential Response as part of the Document structure as defined above, it is a significant deviation that necessitated the definition of a new Credential Format identifier mso_mdoc_authenticated_channel.

credential_response_encryption parameter MUST be present. Note: The wallet can find out about the supported cryptographic algorithms for the credential response encryption by using the Issuer's metadata parameter credential_response_encryption.

Below is a non-normative example of a Credential Request during the PID issuance in IETF SD-JWT VC Credential Format over Authenticated Channel: Note: The wallet can find out about the supported cryptographic algorithms by using the Issuer's metadata parameter credential_signing_alg_values_supported.

POST /credential HTTP/1.1
Host: server.example.com
Content-Type: application/json
Authorization: DPoP czZCaGRSa3F0MzpnWDFmQmF0M2JW
DPoP: ey…

{
  "format": "vc+sd-jwt",
  "vct": "SD_JWT_VC_example",
  "proof": {
    "proof_type": "jwt",
    "jwt": "eyJ0e...h1WlA"
  },
  "verifier_pub": {
    "kty": "EC",
    "crv": "P-256",
    "x": "aPPK-...2-Drn",
    "y": "FqJqG...ksKHp"
  },
  "credential_response_encryption": {
    "jwk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "1SptQyCUQiQD3dBcVHTclxRtcqhZlF1rIKcBR-i_WK4",
      "y": "8ayoQrh52zNuRQx8Q0gpmCpOjzbH397mOsaSi8X10c4"
    },
    "alg": "ECDH-ES",
    "enc": "A256GCM"
  }
}

Implementation Considerations

  • When the issuance flow is specific to the PID Provider, alternatives to Presentation Exchange may be considered. If the issuance flow is to be generic, sticking to PE might be the best option.
  • The JWA to use the x5c in the SD-JWT and perform ECDH key agreement and derive the MAC key is to be defined, a proposal is made here.

Usability Considerations

  • Relying Party should inform users in advance of what is required for the process to be completed successfully and what steps follow
  • It must be clarified whether the wallet app needs to be unlocked in this flow, as no sensitive data is displayed and the user must identify themselves with their ID card and eID PIN in order to successfully complete the process
  • For reasons of transparency and to increase trust, Relying Parties should provide sufficient information (metadata) for the consent screen. This allows users to learn everything relevant e.g. about the relying party itself, privacy and data retention
  • eID process is integrated in Wallet. No context switch to the AusweisApp is required
  • Physical ID card is required for every transaction
  • Online-Ausweisfunktion must be activated
  • eID PIN must be set by the user (replacement of the Transport PIN) and be known to them so that they can successfully confirm the process
  • Only the requested data attributes can be displayed on the consent screen, as the user's data values are not available at this point (only after a successful eID process)
  • It must be ensured that users return to the correct tab in the correct browser in order to continue the process or know how to get there manually if necessary (especially for iOS devices, if the process was not started in the default browser)

Security Considerations

  • In Step 8, a malicious app may spoof the wallet app by registering to the same custom URL scheme; an attacker may
  • on the attacker's own device: Capture the request and replay it to a victim on another device, thus having the victim identify itself in a context of the attacker (Relaying Attack breaking Identification Context); or
  • on the victim's device: Capture the request and spoof the whole identification process or parts of it (Wallet App Spoofing).
  • In Step 10: An attacker acting as an RP can forward a request from a different RP.
  • As long as the request remains unchanged, we're in the Relaying Attack breaking Identification Context
  • If the attacker changes anything in the request, this will break the signature. The attacker could otherwise attempt to
    • insert the attacker's own ephemeral key, leading to an SD-JWT artifact that could be used in a different flow between the attacker and some other RP.
    • modify state or nonce or other data. Q: Any useful attacks resulting from this?
  • In Step 14: Shall the Wallet Attestation be used at the Authorization Request? Which nonce to use for Wallet Attestation at the Token Request?
  • In Step 15 and onward: Security of PID Provider Interface:
  • Are additional steps required to protect the interface to the PID Provider?
  • What exactly is the transaction binding?
  • How is the eID process tied to the process at the PID provider?
  • In Step 37: The RP must not consider the user identified at this point; it is important to have the browser redirect in the later steps.

Privacy Considerations

  • For the user consent, the user should be informed in a meaningful way about the process for which the identification is performed. This includes the RP's domain name or assured legal name (via a certificate), the purpose of the identification and the context. Note: This may have privacy implications that need to be evaluated.
  • The Wallet must ensure that the purpose of the Relying Party is not transmitted to the PID Provider
  • During the presentation of the PID, the PID provider learns which attributes of the PID are presented to the RP. This cannot be solved with B as with B', as the identity attributes are read from the eID-card with B. It would be difficult for the user to understand why all attributes are initially read from the eID-card even if only some of them are to be presented to the RP.
  • Selective Disclosure is achieved by ensuring that the credential contains only those data items (claims) that are requested by the RP. The list of requested claims is part of the request to the PID Provider.
  • An initiating step before the authorization request (Step 10) that is performed without the user's interaction might leak information about the user's device to the RP (Initial Request Privacy Leak). For example:
  • the fact that the wallet app is installed,
  • the fact which wallet app is installed,
  • some metadata about the wallet app contained in request headers (e.g., version, language, etc.),
  • network information if the browser uses a VPN but the wallet app does not.
  • The SessionTranscript is used to bind the authentication to a specific session:
  • The SessionTranscript structure for OpenID4VP contains a OID4VPHandover structure containing:
    • clientIDHash containing the SHA256 of the Relying Parties client_id and the mdocGeneratedNonce
    • responseUriHash containing the SHA256 of the Relying Parties responseUri and the mdocGeneratedNonce
    • nonce chosen by the Relying Party
  • As the relevant information is hashed, the Relying Party identity is not revealed to the PID Provider
  • Unlinkability: Each Relying Party sees a new credential for each use of the flow. Unless the eID data itself enables linkability, there is no information enabling linkablility between different uses of the flow.

Open Questions

  • Should the purpose be included in the KB-JWT?