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
andvalueDigests
are omitted
- no signed hashes are transmitted, i.e.,
- 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:
For SD-JWT VC:
Sequence Diagram¶
User Journey: PID Presentation - Authenticated Channel - eID Card
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.
- User browses to Relying Party (RP) website
- Browser app on the user's device opens the RP website
- RP generates a key pair to be used for ECDH key agreement for SD-JWT HMAC'ing
- RP generates an OpenID4VP Authorization Request and stores it under a
request_uri
(e.g.,https://rp.example.com/oidc/request/1234
); - The request is bound to the user's browser session
- It is signed using a key bound to the RP's metadata that can be retrieved using the RP's client_id
- It contains the ephemeral key for ECDH key agreement for SD-JWT HMAC'ing
- It contains RP's nonce and state
- It contains the RP's response_uri endpoint for sending the Authorization Response over POST
- RP generates a new browser session and binds the generated Authorization Request to it
- 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 - The user clicks on the link
- The RP website navigates to the custom scheme link to launch the wallet app
- The user unlocks the wallet app (see notes below)
- The wallet app retrieves the Authorization Request from the RP website (e.g.,
https://rp.example.com/oidc/request/1234
) - The wallet app receives the Authorization Request
- 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.
- The Wallet displays information about the identity of the Relying Party and the purpose, the user gives consent to present the PID.
- The Wallet fetches fresh wallet attestation from the Wallet Provider backend.
- The Wallet requests a fresh nonce for the wallet attestation nonce from the PID Provider (wallet attestation nonce).
- The PID Provider generates a fresh nonce linked to the issuance session.
- The PID Provider returns the wallet attestation nonce to the Wallet.
- The Wallet generates a Wallet Attestation PoP and signs it with device_priv; containing
- audience
- expiration time
- wallet attestation nonce
- 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
- 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.
- The PID Provider returns a request_uri that is bound to the Pushed Authorization Request.
- The Wallet sends the Authorization Request; containing
- the PAR request_uri
- 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.
- Further communication is exchanged to perform the eID process
- The user provides the eID PIN to the wallet app.
- Further communication is exchanged to perform the eID process
- 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.
- The PID Provider responds to the Wallet with an Authorization Response; containing
- the auth code
- 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
- 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.
- The PID Provider sends a Token Response; containing
- DPoP-bound access token
- a c_nonce
- The Wallet generates a new ephemeral keypair (cre_eph_pub, cre_eph_priv).
- 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
- (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.
- (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"
- (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.
- (SD-JWT) The Wallet generates an ephemeral key pair for the KB-JWT (kb_eph_pub, kb_eph_priv) and signs the nonce
- (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
- (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.
- 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.
- (mdoc) The PID Provider creates the mdoc deviceAuth (using the MAC key) containing
- the user claims
- the OpenID4VP SessionTranscript(mdocGeneratedNonce, client_id, responseUri, nonce)
- (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. - (mdoc) The PID Provider sends the Credential Response JWT; containing:
- PID as mdoc
- (mdoc) The Wallet decrypts the Credential Response JWT using the cre_eph_priv and retrieves the PID.
- (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
- (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. - (SD-JWT) The PID Provider sends the Credential Response JWT; containing:
- PID as SD-JWT VC
- (SD-JWT) The Wallet decrypts the Credential Response JWT using the cre_eph_priv and retrieves the PID.
- (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.
- The wallet app creates a VP token and a presentation submission from the received SD-JWT PID.
- 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
- The wallet app sends the VP token and presentation submission to the RP (encrypted to the RP's public key rp_eph_pub).
- The RP finds a session with the state and generates a response_code for this session
- The RP returns the redirect_uri with the response_code to the wallet app
- The wallet app launches the browser with the redirect_uri and response_code.
- The browser sends the redirect_uri and response code to the RP, attaching the browser session id as a cookie.
- The RP looks up whether there exists a session with the session id from the cookie and a matching response_code
- 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.
- (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.
- (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
- 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:
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 thehttps
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:
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?