9.1.4.2.3. Key Attestation Issuance

This section describes how the Wallet Provider issues Key Attestations.

Use of the Key Attestation APIs (OEM) is defined in Use of Key Attestation APIs (OEM).

The figure illustrates the Sequence Diagram for Key Attestations acquisition.

Fig. 9.5 Sequence Diagram for Key Attestations acquisition.

Step 1: The User initiates a new operation that necessitates the acquisition of a Key Attestation.

Steps 2-3: The Wallet Instance MUST:

  1. Verify the existence of Cryptographic Hardware Keys. If none exist, Wallet Instance re-initialization is required (WP_140a).

  2. Verify the Wallet Provider's federation membership and retrieve its metadata (WP_023).

Steps 4-6 (Nonce Retrieval): The Wallet Instance requests a nonce value from the Wallet Solution Nonce Endpoint of the Wallet Provider Backend (WP_140b). The nonce is required to be unpredictable and serves as the main defense against replay attacks.

The nonce MUST ensure single-use within a predetermined time frame.

Upon a successful request, the Wallet Provider generates and returns the nonce value to the Wallet Instance.

Steps 7-9 (Credential key generation): The Wallet Instance MUST generate one or a batch of asymmetric Credential key pairs to be attested (key_pub_1, key_priv_1, ..., key_pub_n, key_priv_n) only after the nonce is available.

On Android, the Wallet Instance MUST generate each key pair through the Key Attestation API. It MUST set the attestation challenge to the UTF-8 octets of the nonce. The API returns the public key and a signed key_attestation for that key. The Wallet Instance MUST NOT use client_data_hash as that challenge. client_data_hash depends on the JWK thumbprint of the key, and the platform binds the challenge at key generation time.

On iOS, the Wallet Instance MUST generate each key pair in the Secure Enclave. The integrity assertion for each key is requested after client_data_hash has been computed.

Step 10: The Wallet Instance performs the following actions (WP_140c):

  • Creates client_data, a JSON object that includes the nonce and a jwk_thumbprints field containing a JSON array of the JWK thumbprints corresponding to the public keys (key_pub_1,...,key_pub_n).

  • Computes client_data_hash by applying the SHA256 algorithm to the client_data.

Below is a non-normative example of the client_data JSON object.

{
  "nonce": "i4ThI2Jhbu81i8mqyWEuDG5t",
  "jwk_thumbprints": ["vbeXJksM45xphtANnCiG6mCyuU4jfGNzopGuKvogg9c"]
}

Steps 11-12: The Wallet Instance produces a hardware_signature value by signing the client_data_hash with the Wallet Hardware's private key, serving as a proof of possession for the Cryptographic Hardware Keys (WP_140d).

The Key Attestation Request MUST NOT include a top-level integrity_assertion. The Wallet Provider checks the revocation status of the Wallet Instance Attestation before issuing a Key Attestation. On iOS, the per-key integrity assertion is carried inside keys_to_attest, because that platform does not provide a key attestation API.

Steps 13-16: The Wallet Instance constructs keys_to_attest as a JSON array of JWTs. The header and claims of each JWT are defined in Key Attestation Element.

  • On Android, when Key Attestation APIs (OEM) are used, each JWT carries the key_attestation obtained at key generation in wscd_key_attestation.attestation.

  • On iOS, the Wallet Instance requests from the Device Integrity Service an integrity_assertion for each key, bound to client_data_hash, and places that value in wscd_key_attestation.integrity_assertion.

Each JWT MUST be signed with the private key of the Credential key pair it attests.

Steps 17-18 (Key Attestation Issuance Request): The Wallet Instance:

  • Constructs the Key Attestation Request in the form of a JWT. This JWT includes keys_to_attest, hardware_signature, nonce, hardware_key_tag, cnf, platform and other configuration related parameters (see Table of the Key Attestation Request Body). The Key Attestation Request MUST be signed using the private key related to the public key included in the request, using the cnf parameter (first element of keys_to_attest) (WP_140–141).

  • Submits the Key Attestation Request to the Key Attestation Issuance Endpoint of the Wallet Provider Backend.

The Wallet Instance MUST send the signed Key Attestation Request JWT as an assertion parameter in the body of an HTTP request to the Wallet Provider's Key Attestation Issuance Endpoint (WP_142).

Steps 19-24: The Wallet Provider Backend evaluates the Key Attestation Request and MUST perform the following checks (WP_143):

  1. The request MUST include all required HTTP header parameters as defined in Key Attestation Issuance Request (WP_143a).

  2. The signature of the Key Attestation Request MUST be valid and verifiable using the provided jwk (WP_143b).

  3. The nonce value MUST have been generated by the Wallet Provider and not previously used (WP_143c).

  4. A valid and currently registered Wallet Instance associated with the provided hardware_key_tag MUST exist (WP_143d). The Wallet Provider MUST reject the request when the Wallet Instance Attestation of that Wallet Instance is revoked.

  5. The signature of each JWT in keys_to_attest MUST be validated using the jwk of that element. If wscd_key_attestation.attestation is present, the Wallet Provider MUST validate it according to the device manufacturer's guidelines, as defined in Use of Key Attestation APIs (OEM) (WP_143h). The challenge embedded in that attestation MUST be equal to the UTF-8 octets of the nonce. The attested public key MUST match the cnf JWK of the same element. If wscd_key_attestation.integrity_assertion is present, the Wallet Provider MUST validate it according to the device manufacturer's guidelines.

  6. The client_data MUST be reconstructed using the nonce and their respective thumbprint JWKs [key_pub_1,...,key_pub_n]. The hardware_signature parameter value is then validated using the registered Cryptographic Hardware Key's public key associated with the Wallet Instance (WP_143e).

  7. The device in use MUST be free of known security flaws and meet the minimum security requirements defined by the Wallet Provider.

  8. The URL in the iss parameter MUST match the Wallet Provider's URL identifier (WP_143g).

Upon successful completion of all checks, the Wallet Provider issues a Key Attestation valid for at least one month.

Step 25 (Key Attestation Issuance Response): Upon successful completion, the Wallet Provider MUST return a confirmation response using status code set with 200 and Content-Type application/json. The response MUST contain the Key Attestations signed by the Wallet Provider using the JWT format. The Wallet Instance MUST perform security and integrity verification of the Key Attestations received, along with the trust verification already evaluated about the Issuer (WP_030–031).

Below is a non-normative example of the response.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "key_attestation": "omppc3N1ZXJBdXRohEOhASaiBE...dElEAnFlbGVtZW50SWRl"
}