opendi4vp-offline | November 2022 | |
Yasuda, et al. | Standards Track | [Page] |
This document defines how Bluetooth Low Energy (BLE) can be used to request presentation of verifiable credentials. It uses request and response syntax as defined in [OpenID4VP].¶
This document enables Wallets and the Verifiers who have implemented [OpenID4VP] to request and receive verifiable presentations even if one or both of the entities do not have Internet connection by utilizing Bluetooth Low Energy (BLE). This document uses request and response syntax as defined in [OpenID4VP].¶
This draft uses the terms and definitions from [OpenID4VP], section 2.¶
The user needs to present her electronic ticket (represented by a verifiable credentioal) when entering a venue. She opens her wallet and authenticates towards the wallet. She then scans the QR code at the entrance with her wallet. The wallet determines the credential (the ticket) required by the verifier and asks for consent to share the respective credential. The credential is then transmitted to the verifier, which, after validation, allows her to enter the venue, e.g. by opening the turnstile.¶
This specification supports deployments, where the Verifier or the Wallet or both parties do not have an Internet connection or where use of an Internet connection is not desired.¶
The protocol consists of the following steps:¶
Establishing a BLE connection¶
Verifying the parties¶
Exchanging verifiable credentials¶
Finalizing the exchange¶
Wallet and the Verifier MUST implement BLE according to the [Bluetooth.4.Core] specification .¶
During step 1, ephemeral keys to encrypt the session are exchanged.¶
Step 2 utilizes request and response syntax as defined in [OpenID4VP]. Identification and authentication of Verifier and Wallet can be implemented utilizing the established OpenID mechanisms (e.g. client id).¶
The following limitations in BLE stack 4.2 need to be considerate:¶
Below is the diagram that illustrates protocol flow:¶
Verifier and the Wallet establish the connection. This specification defines two mechanisms to do so: QR code displayed by the Verifier and BLE Advertisement initiated by the Verifier.¶
Wallet obtains the Presentation Request from the Verifier.¶
Wallet authenticates the user and obtains consent to share Credential(s) with the Verifier.¶
Wallet sends the Presentation Response to the Verifier containing Verifiable Presentation(s).¶
Verifier and the Wallet close connection.¶
First, Verifier and the Wallet need to establish the connection. This specification defines two mechanisms to do so: BLE Advertisement initiated by the Verifier and QR code displayed by the Verifier.¶
Wallet and the Verifier MUST support LE Data Packet Length Extension according to [Bluetooth.4.2.Core] section 4.5.10.¶
Speaking in BLE terms, the Verifier takes the role of the "Peripheral GAP Role" whereas the Wallet takes the "Central GAP Role", i.e. the Verifier advertises the OpenID 4 VP service and the Wallet drives the protocol flow by reading data from and writing data to the Verifier.¶
This section describes how Verifier and the Wallet can establish a connection by Verifier initiating BLE Advertisement. This mechanism can be used by the Verifiers when the use-case does not allow the End-Users to scan a QR code displayed on the Verifier's device, for example to ensure the safety of the Verifier.¶
The following figure shows the message exchange.¶
+------------+ +-----------+ | |-----PDU ADV_IND------>| | | Advertiser |<----SCAN_REQ----------| Scanner | | (Verifier) |-----SCAN_RESP-------->| (Wallet) | | |<----IDENTIFY_REQ------| | +------------+ +-----------+¶
Pre-requisites: The Verifier has opened it's application and started the mode that accepts OpenID4VP.¶
Verifier app starts BLE advertisement (PDU ADV_IND
). (announcing the first half of the verifier's key)¶
Wallet scans the BLE layer and filters the OpenID4VP automatically (in case it found only one). If there are multiple verifiers the user is asked to choose.¶
Wallet connects to the Verifier (SCAN_REQ
). The second half of the verifiers key is provided in the scan response (SCAN_RESP
).¶
Wallet generates a X25519 ([RFC7748]) keys of its own and combines to create a DHE secret key.¶
Wallet makes identify request (IDENTIFY_REQ
) and submits its keys to the verifier in plain text (see below). #identify characteristics¶
Verifier calculates DHE secret key based on its key and the wallet's key.¶
Note: While the Verifier can be active for a long time and process multiple Connections (based on the same Verifier key) subsequently, the Verifier can only accept a single connection at a time.¶
BLE Advertisement Packet structure MUST be the following:¶
PDU: Header: PDU type: ADV_IND Tx Address: Random Rx Address: Random Payload: (37 bytes) Adv Address: Random address Adv Data: (32 byte) Adv Type: Complete Local Name flag: "LE General Discoverable Mode", "BR/EDR Not Supported" Data: OVP_STADIONENTRANCE_8520f0098930a754748b7ddcb43ef75a (5 bytes + 16 bytes ) Half of the random X25519 public key¶
The data in the Advertisement Packet contain the prefix "OVP" indicating that the verifier is ready to accept connections for OpenID 4 VPs. A human readable name of the verifier is given in the next part delimited by a leading and a trailing "-". The rest of the data packet after the "_" contain the first half of its public key (example: 8520f0098930a754748b7ddcb43ef75a) (max. available size 29 byte).¶
Note: The remaining half of the key (16 byte of X25519 ([RFC7748]) - example: 0dbf3a0d26381af4eba4a98eaa9b4e6a) is being sent during the scan response.¶
This section describes how Verifier and the Wallet can establish connection by Verifier displaying a QR Code scanned using the Wallet.¶
The following figure shows the message exchange.¶
+------------+ +-----------+ | |<----Scan_QR_Code------| | | Advertiser |<----SCAN_REQ----------| Scanner | | (Verifier) |-----SCAN_RESP-------->| (Wallet) | | |<----IDENTIFY_REQ------| | +------------+ +-----------+¶
Pre-requisites: The Verifier has opened it's application and displays a QR Code.¶
The user scans the QR Code (Scan_QR_Code
), typically the wallet app, which contains the advertisment data as described in Section 7.1.¶
All other steps are conducted as described in Section 7.1.¶
The data are encoded in an URL as follows:¶
The URL starts with the ustom scheme OVPBLE
. The encoding of the actual data in the URL path follows the same rules given in Section 7.1:¶
The first part delimited by a "_" is a human readable identifier of the Verifier (RP)¶
The rest of the path contains the first half of the verifier's ephemeral X25519 key in base64url encoding (as defined in Section 5 of [RFC4648]).¶
Here is an example:¶
OVPBLE://STADIONENTRANCE_ODUyMGYwMDk4OTMwYTc1NDc0OGI3ZGRjYjQzZWY3NWE¶
On the BLE layer, the Wallet reads the following characteristics from the Verifier:¶
Request Size (00000004-5026-444A-9E0E-D6F2450F3A77): used to obtain the size of the presentation request (calculation see below).¶
Request (00000005-5026-444A-9E0E-D6F2450F3A77): used to obtain the actual JSON payload constituting the presentation request.¶
The JSON payload is encoded using JWS Compact serialization. The request size is the number of bytes that will be sent over BLE, the size of (JWS) in bytes¶
Note: Entire payload is encrypted on the BLE layer using the session key determined as defined above.¶
The Request (00000005-5026-444A-9E0E-D6F2450F3A77) contains a signed request object containing the parameters as defined in [OpenID4VP].¶
The following request parameters are supported by this specification:¶
iss
: REQUIRED. MUST contain the verifier's client_id.¶
presentation_definition
: CONDITIONAL. contains the verifier's requirements regarding verifiable credentials it wants to obtain from the wallet.
MUST not be present if a 'scope' parameter is present.¶
scope
: CONDITIONAL. The scope value MUST represent a credential presentation request. This parameter MUST NOT be present if a presentation_definition
parameter is present.¶
nonce
: REQUIRED. This value is used to securely bind the verifiable presentation(s) provided by the wallet to the particular transaction.¶
aud
: OPTIONAL. This value identifies the wallet issuer (as intended recipient of the presentation request).¶
The parameters response_type
and redirect_uri
MUST NOT be present in the request.¶
The following is a non normative example of a request before signing:¶
{ "iss":"s6BhdRkqt3", "aud":"https://wallet.example.com", "nonce":"n-0S6_WzA2Mj", "presentation_definition":{ "id":"example", "input_descriptors":[ { "id":"id_credential", "format":{ "jwt_vc":{ "proof_type":[ "JsonWebSignature2020" ] } }, "constraints":{ "fields":[ { "path":[ "$.vc.type" ], "filter":{ "type":"array", "contains":{ "const":"IDCredential" } } } ] } } ] } }¶
On the BLE layer the wallet writes the following characteristics in order to send a presentation response:¶
Response Size (00000007-5026-444A-9E0E-D6F2450F3A77): used to transmit the content size of the presentation response¶
Submit Response (00000008-5026-444A-9E0E-D6F2450F3A77): used to write the JSON payload of the presentation response as chunks.¶
Note: All payload is encrypted on the BLE layer using the session key determined as defined above.¶
The response contains the parameters as defined in Section 6 of [!@OpenID4VP] in JSON encoding.¶
The following is a non normative example of a response before signing:¶
{ "presentation_submission":{ "definition_id":"example", "id":"id_credential", "descriptor_map":[ { "id":"id_credential", "path":"$", "format":"jwt_vp", "path_nested":{ "path":"$.vp.verifiableCredential[0]", "format":"jwt_vc" } } ] }, "vp_token":"eyJhbGciOiJFUzI...XK9n2861OaHDQ" }¶
The Verifier acts as the server and the Verifier service MUST contain the following characteristics:¶
Verifier Service UUID MUST be 00000001-5026-444A-9E0E-D6F2450F3A77
.¶
Characteristic name | UUID | Type | Description |
---|---|---|---|
Request Size | 00000004-5026-444A-9E0E-D6F2450F3A77 | Read | Get the request size |
Request | 00000005-5026-444A-9E0E-D6F2450F3A77 | Read | Get the request JSON |
Identify | 00000006-5026-444A-9E0E-D6F2450F3A77 | Write | Wallet identifies |
as chunks | |||
Response Size | 00000007-5026-444A-9E0E-D6F2450F3A77 | Write | Submit the content |
size | |||
Submit Response | 00000008-5026-444A-9E0E-D6F2450F3A77 | Write | VC stream as chunks |
+--------------------+--------------------------------------+-----------------------+---------------------+¶
TODO: Can we plan to register our service with Bluetooth SIG? This will allow us to have¶
ToDo: If 'Submit VC' latency is high due to the presence of a photograph we will fall back to the style that Kritina wrote with State.¶
ToDo: Check if there are conventions to the UUID. Original in ISO is 00000001-A123-48CE-896B-4C76973373E6
.¶
Using the 'Content Size' characteristics the wallet sets the size. Once we receive the confirmation about the write we start the 'Submit VC' as a stream. 'Submit VC' is called multiple times until all the data is sent.¶
NOTE: Limit the total size to ~4kb
for better performance while the protocol can handle larger. In case the Request does not match Size then its assumed its corrupted and the same procedure is repeated again.¶
Clarify the error handing rationale¶
The Request Size
is first called to get the actual size of the request. Once the size of the request is obtained the Request
characteristics is called to get the actual data. The characteristics is called repeatedly until all the requested data is received.¶
To read the complete Characteristic Value an ATTREADREQ PDU should be used for the first part of the value and ATTREADBLOBREQ PDUs shall used for the rest. The Value Offset parameter of each ATTREADBLOBREQ PDU shall be set to the offset of the next octet within the Characteristic Value that has yet to be read. The ATTREADBLOBREQ PDU is repeated until the ATTREADBLOBRSP PDU's Part Attribute Value parameter is shorter than (ATT_MTU - 1).¶
NOTE: In case the Request does not match Size then its assumed its corrupted and the same procedure is repeated again.¶
After data retrieval, the GATT client unsubscribes from all characteristics.¶
In case of a lost connection a full flow is conducted again.¶
The session MUST be terminated if at least one of the following conditions occur:¶
After a time-out of no activity occurs.¶
If the Wallet does not want to receive any further requests.¶
If the Verifier does not want to send any further requests.¶
Termination is as per the default BLE write.¶
In case of a termination, the Wallet and Verifier MUST perform at least the following actions:¶
Destruction of session keys and related ephemeral key material¶
Closure of the communication channel used for data retrieval.¶
[SASI] TODO: Should we support multiple encryption type or pick the single encryption route?¶
The Wallet obtains Verifier's ephemeral key pair in the Connection Setup Request from BLE Advertisement or a QR Code.¶
The Wallet generates an ephemeral key pair.¶
The Wallet communicates its ephemeral key pair to the Verifier in the Identity Request.¶
The Verifier derives an encryption key using the Wallet's public key received in the Idenity Request, and encrypts Presentation Request using it.¶
The Wallet derives an encryption key using the Verifier's public key received in the Connection Set Up phase, decrypts Presentation Request and encrypts Presentation Response using it.¶
The Verifier decrypts Presentation Response using the encryption key computed in step 4.¶
Note that Connection Setup Request itself defined in Section 7 MUST NOT be encrypted.¶
ToDo: no algorithm identifier since looks like we are doing only X25519?¶
To calculate the session keys, the Wallet and the Verifier MUST perform ECKA-DH (Elliptic Curve Key Agreement Algorithm - Diffie-Hellman) as defined in BSI TR-03111. The Zab output defined in BSI TR-03111 MUST be used to derive 2 keys.¶
The Verifier MUST derive session key using HKDF as defined in [RFC5869] with the following parameters:¶
The Wallet MUST derive session key using HKDF as defined in [RFC5869] with the following parameters:¶
For encryption AES-256-GCM (192) (GCM: Galois Counter Mode) as defined in NIST SP 800-38D or ChaCha20 [RFC8439] MUST be used.¶
ToDo: Can we do ChaCha20? Rather than AES 256 GCM? The fact that ChaCha20 is more streaming.¶
The IV (Initialization Vector defined in NIST SP 800-38D) used for encryption MUST have the default length of 12 bytes for GCM, as specified in NIST SP 800-38D. The IV MUST be the concatenation of the identifier and the message counter (identifier || message counter). The identifier MUST be an 8-byte value.¶
The Verifier MUST use the following identifier: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00. The Wallet MUST use the following identifier: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01.¶
The Wallet and Verifier MUST keep a separate message counter for each session key. The message counter value MUST be a 4-byte big-endian unsigned integer. For the first encryption with a session key, the message counter MUST be set to 1. Before each following encryption with the same key, the message counter value MUST be increased by 1. A message counter value MUST never be reused in any future encryption using the same key. The AAD (Additional Authenticated Data defined in NIST SP 800-38D) used as input for the GCM function MUST be an empty string. The plaintext used as input for the GCM function MUST be Wallet request or Wallet response. The value of the data element in the session establishment and session data messages as defined in 9.1.1.4 MUST be the concatenation of the ciphertext and all 16 bytes of the authentication tag (ciphertext || authentication tag).¶
Both wallet and the Verifier MUST remove all the information about the session after its termination.¶
To ensure that the Wallet is connected to the correct Verifier. The Wallet may verify the Ident characteristic as described in Clause 8.3.3.1.4. The Ident characteristic value MUST be calculated using the following procedure:¶
Use HKDF an defined in [RFC5869] with the following parameters: * Hash: SHA-256 * IKM: EdeviceKeyBytes (see Clause 9.1.1.4) * salt: (no salt value is provided) * info:"BLEIdent" (encoded as ASCII string) * L: 16 octets If the Ident characteristic received from the Verifier does not match the expected value, the Wallet MUST disconnect from the Verifier.¶
NOTE The purpose of the Ident characteristic is only to verify whether the Wallet is connected to the correct Verifier before setting starting OpenID4VP Request. If the Wallet is connected to the wrong Verifier, session establishment will fail. Connecting and disconnecting to an Verifier takes a relatively large amount of time and it is therefore fastest to implement methods to identify the correct Verifier to connect to and not to rely purely on the Ident characteristic to identify the correct Verifier.¶
How does the wallet authenticate the Verifier? The verifier signs the presentation request.¶
How does the Verifier know a particular response is tied to a particular request? It evaluates the nonce and aud value of the presentation to match the nonce of the request and its client id.¶
[[ To be removed from the final specification ]]¶
-00¶
initial revision¶