Wallet Attestation IssuanceΒΆ
This section describes how the Wallet Provider issues a Wallet Attestation.
Step 1: The User initiates a new operation that necessitates the acquisition of a Wallet Attestation.
Steps 2-3: The Wallet Instance MUST:
Verify the existence of Cryptographic Hardware Keys. If none exist, Wallet Instance re-initialization is required.
Generate an ephemeral asymmetric key pair for Wallet Attestation, linking the public key to the attestation.
Verify the Wallet Provider's federation membership and retrieve its metadata.
Steps 4-6 (Nonce Retrieval): The Wallet Instance solicits a one-time "challenge" from the Nonce endpoint of the Wallet Provider Backend. This "challenge" takes the form of a nonce
, which is required to be unpredictable and serves as the main defense against replay attacks.
The nonce
MUST be produced in a manner that ensures its single-use within a predetermined time frame.
Below is a non-normative example of a Nonce Request.
GET /nonce HTTP/1.1
Host: walletprovider.example.com
Upon a successful request, the Wallet Provider generates and returns the nonce value to the Wallet Instance. Below is a non-normative example of a Nonce Response.
HTTP/1.1 200 OK
Content-Type: application/json
{
"nonce": "d2JhY2NhbG91cmVqdWFuZGFt"
}
Step 7: The Wallet Instance performs the following actions:
Creates
client_data
, a JSON object that includes the challenge and the thumbprint of ephemeral publicjwk
.Computes
client_data_hash
by applying theSHA256
algorithm to theclient_data
.
Below is a non-normative example of the client_data
JSON object.
{
"challenge": "0fe3cbe0-646d-44b5-8808-917dd5391bd9",
"jwk_thumbprint": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c"
}
Steps 8-10: The Wallet Instance:
produces an
hardware_signature
value by signing theclient_data_hash
with the Wallet Hardware's private key, serving as a proof of possession for the Cryptographic Hardware Keys.requests the Device Integrity Service to create an
integrity_assertion
value linked to theclient_data_hash
.receives a signed
integrity_assertion
value from the Device Integrity Service, authenticated by the OEM.
Note
integrity_assertion
is a custom payload generated by Device Integrity Service, signed by device OEM and encoded in base64 to have uniformity between different devices.
Steps 11-12 (Wallet Attestation Issuance Request): The Wallet Instance:
Constructs the Wallet Attestation Request in the form of a JWT. This JWT includes the
integrity_assertion
,hardware_signature
,challenge
,hardware_key_tag
,cnf
and other configuration related parameters (see Table of the Wallet Attestation Request Body) and is signed using the private key of the initially generated ephemeral key pair.Submits the Wallet Attestation Request to the Wallet Attestation Issuance endpoint of the Wallet Provider Backend.
Below is a non-normative example of the Wallet Attestation Request JWT without encoding and signature applied:
{
"alg": "ES256",
"kid": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
"typ": "war+jwt"
}
.
{
"iss": "https://wallet-provider.example.org/instance/vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
"sub": "https://wallet-provider.example.org/",
"challenge": "6ec69324-60a8-4e5b-a697-a766d85790ea",
"hardware_signature": "KoZIhvcNAQcCoIAwgAIB...redacted",
"integrity_assertion": "o2NmbXRvYXBwbGUtYXBwYX...redacted",
"hardware_key_tag": "WQhyDymFKsP95iFqpzdEDWW4l7aVna2Fn4JCeWHYtbU=",
"cnf": {
"jwk": {
"crv": "P-256",
"kty": "EC",
"x": "4HNptI-xr2pjyRJKGMnz4WmdnQD_uJSq4R95Nj98b44",
"y": "LIZnSB39vFJhYgS3k7jXE4r3-CoGFQwZtPBIRqpNlrg"
}
},
"vp_formats_supported": {
"jwt_vc_json": {
"alg_values_supported": ["ES256K", "ES384"]
},
"jwt_vp_json": {
"alg_values_supported": ["ES256K", "EdDSA"]
},
},
},
authorization_endpoint": "https://wallet-solution.digital-strategy.europa.eu/authorization",
"response_types_supported": [
"vp_token"
],
"response_modes_supported": [
"form_post.jwt"
],
"request_object_signing_alg_values_supported": [
"ES256"
],
"iat": 1686645115,
"exp": 1686652315
}
The Wallet Instance MUST send the signed Wallet Attestation Request JWT as an assertion
parameter in the body of an HTTP request to the Wallet Provider's Wallet Attestation Issuance endpoint.
Below is a non-normative example of a Wallet Attestation Issuance Request.
POST /wallet-attestation HTTP/1.1
Host: wallet-provider.example.org
Content-Type: application/json
{
"assertion": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImtoakZWTE9nRjNHeG..."
}
Steps 13-17: The Wallet Provider Backend evaluates the Wallet Attestation Request and MUST perform the following checks:
The request MUST include all required HTTP header parameters as defined in Table of the Wallet Attestation Request Header.
The signature of the Wallet Attestation Request MUST be valid and verifiable using the provided
jwk
.The
challenge
value MUST have been generated by the Wallet Provider and not previously used.A valid and currently registered Wallet Instance associated with the provided MUST exist.
The
client_data
MUST be reconstructed using thechallenge
and thejwk
public key. Thehardware_signature
parameter value is then validated using the registered Cryptographic Hardware Key's public key associated with the Wallet Instance.The
integrity_assertion
MUST be validated according to the device manufacturer's guidelines. The specific checks performed by the Wallet Provider are detailed in the operating system manufacturer's documentation.The device in use MUST be free of known security flaws and meet the minimum security requirements defined by the Wallet Provider.
The URL in the
iss
parameter MUST match the Wallet Provider's URL identifier.
Upon successful completion of all checks, the Wallet Provider issues a Wallet Attestation valid for a maximum of 24 hours.
Below is a non-normative example of the Wallet Attestation without encoding and signature applied:
{
"alg": "ES256",
"kid": "5t5YYpBhN-EgIEEI5iUzr6r0MR02LnVQ0OmekmNKcjY",
"trust_chain": [
"eyJhbGciOiJFUz...6S0A",
"eyJhbGciOiJFUz...jJLA",
"eyJhbGciOiJFUz...H9gw",
],
"typ": "wallet-attestation+jwt",
}
.
{
"iss": "https://wallet-provider.example.org",
"sub": "vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c",
"aal": "https://trust-list.eu/aal/high",
"cnf":
{
"jwk":
{
"crv": "P-256",
"kty": "EC",
"x": "4HNptI-xr2pjyRJKGMnz4WmdnQD_uJSq4R95Nj98b44",
"y": "LIZnSB39vFJhYgS3k7jXE4r3-CoGFQwZtPBIRqpNlrg"
}
},
"authorization_endpoint": "https://wallet-solution.digital-strategy.europa.eu/authorization",
"response_types_supported": [
"vp_token"
],
"response_modes_supported": [
"form_post.jwt"
],
"vp_formats_supported": {
"dc+sd-jwt": {
"sd-jwt_alg_values": [
"ES256",
"ES384"
]
}
},
"request_object_signing_alg_values_supported": [
"ES256"
],
"iat": 1687281195,
"exp": 1687288395
}
Step 18 (Wallet Attestation Issuance Response): Upon successful completion, the Wallet Provider MUST return a confirmation response, containing the Wallet Attestation signed by the Wallet Provider. The Wallet Instance will then perform security, integrity, and trust verification of the Wallet Attestation and its issuer.
Below is a non-normative example of a Wallet Attestation Issuance Response.
HTTP/1.1 200 OK
Content-Type: application/jwt
eyJhbGciOiJFUzI1NiIsInR5cCI6IndhbGx ...