OVIP: 7
Title: Session Layer
Author: David Riegelnig <david.riegelnig@bitcoinsuisse.com>
Discussions-To: https://community.openvasp.org/#narrow/stream/21-protocol-.2F.20ovip
Status: Accepted
Type: Standard
Created: 2020-05-28
This OVIP refines the session layer of the OpenVASP protocol. The message structure is streamlined and redefined to better abstract from lower protocol layers. A more formal session state model is introduced along with the ability to abort running sessions. Rules for application messages ensure consistency for protocol extensions.
The OpenVASP protocol is defined as a stack of layers as described in OVIP-0009 (Layer Model). This OVIP refines the Session Layer (Layer 5), which provides functionality to open, control and end the dialog between two VASPs, not only on a technical but also on a business level. It provides context to a set of messages and ensures authenticity and auditability of all messages send within one session.
Message
Message conformant to the specification provided below.
Sender
VASP sending a Message.
Receiver
VASP receiving a Message.
Messages are serialized into bytes and must contain the following elements:
Signature
(fixed length, see 2.2.2)Content
encoded in JSON as specified in RFC 8259 (see below)
Level 1 | Name | Type | Description |
---|---|---|---|
Header | header |
Object | See 2.2.1 |
Body | body |
Object | Contains elements depending on message type |
The signature is prepended to the serialized Content
bytes.
header
is a JSON object and must contain the following elements:
Level 2 | Name | Type | Description |
---|---|---|---|
Version | version |
String | Fixed value: 1.0 |
Sender | sender |
Hex(32-bit) | VASP Identifier of the Sender |
Receiver | receiver |
Hex(32-bit) | VASP Identifier of the Receiver |
Message identifier | msgid |
Hex(128-bit) | Randomly set |
Session identifier | session |
Hex(128-bit) | See 4.1 |
Message type | type |
String | See 4.1 / 4.2 / 4.3 / 4.4 |
ECDH Public Key | ecdhpk |
Hex(33-Bytes) | See 4.1 / 4.2 |
The value assigned to sig
is the cryptographic signature of the content
object generated by the Sender. Signature must be verifiable with the public signingKey
available from the Sender's VASP Contract, which is retrieved from the Index Contract using the Sender's VASP Code (part of the value assigned to sender
).
Session Request and Session Reply Messages are encrypted with a shared key derived from the public messageKey
available from the Receiver's VASP Contract and the Sender's private messageKey
using secp256k1.
All subsequent messages are encrypted with a session specific shared secret derived from (ecdhpA,ecdhskB) or (ecdhskA,ecdhpkB) respectively where(ecdhskA,ecdhpkA) and (ecdhskB,ecdhpkB) are ephemeral key pairs generated by the intiating and responding VASP respectively.
Encryption uses the standard Elliptic Curve Integrated Encryption Scheme with SECP-256k1 public key and AES GCM algorithm with random 96-bit nonce and 16 byte authentication tag. The 96-bit nonce is prepended to the resulting ciphertext.
Session
Bidirectional exchange of related Messages between two VASPs.
Session Messages
Messages of specified types used to initiate, accept, decline, close and abort a Session.
Initiator
VASP initiating a Session.
Responder
VASP responding to a Session initiation.
Exception
Error or unexpected event ocurring to one of the parties during a Session, e.g. receiving an incorrect Message or the absence of a response.
Exception Handling
Process of observing and responding to an Exception.
A Session can exist in several states as listed in the table below. Given the asynchronous nature of exchanged Messages, the Session states of the Initiator and the Responder will temporarily differ until state-changing Messages are received. In case of an Exception, the Sessions of the two VASPs can end in different states.
State | Description | Applicable to |
---|---|---|
initiated |
Responder has been asked to join the session; no response yet | Initiator |
invited |
Request to join a session has been received; answer is pending | Responder |
declined |
Session declined by the Responder | Initiator, Responder |
open |
Session was accepted by the Responder and is active | Initiator, Responder |
closed |
Session was orderly closed by the Initiator | Initiator, Responder |
aborted |
Session was aborted by either of the VASPs due to an exception | Initiator, Responder |
The Session is initiated by a Message of type Session Request
(see 4.1 for details).
Start | Message Type | Activity | Actor | State before | State after | Outcome |
---|---|---|---|---|---|---|
1 | Session Request | sent by | Initiator | (none) | initiated |
2 |
2 | Session Request | received by | Responder | (none) | invited |
3 |
A Message of type Session Reply
is sent to respond to a Session initiation (see 4.2 for details).
Start | Message Type | Activity | Actor | State before | State after | Outcome |
---|---|---|---|---|---|---|
3 | Session Reply | sent by | Responder | invited |
declined |
4a |
3 | Session Reply | sent by | Responder | invited |
open |
4b |
4a | Session Reply | received by | Initiator | initiated |
declined |
5 |
4b | Session Reply | received by | Initiator | initiated |
open |
6 |
The choice whether to decline or accept entering into the Session initiated by the Initiator is encoded in the response.
If declined, the interaction ends with a Session in state declined
for both the Initiator and the Responder once the Message is received (outcome 5). If accepted, the Session is in state open
for both VASPs once the Message is received (outcome 6).
A Session in state open
is required for the exchange of application-related Messages (see 5. Application Layer).
The Session is ended by a Message of type Termination
(see 4.3 for details), which is always sent by the Initiator.
Start | Message Type | Activity | Actor | State before | State after | Outcome |
---|---|---|---|---|---|---|
6 | Termination | sent by | Initiator | open |
closed |
7 |
7 | Termination | received by | Responder | open |
closed |
8 |
Aborting a Session is done by sending a Session Abort
Message (see 4.4 for details).
Sessions in state open
can be aborted by either of the VASPs at any time to react to Exceptions or out of operational necessity. In addition, the Initiator can abort a Session in state initiated
.
There is no need aborting a Session in state invited
as the Responder can send a decline Session Reply
Message instead. It further makes no sense aborting a session being in one of the states declined
, closed
or aborted
already.
The next two sections list all possible combinations that can occur when a Session is aborted by either the Initiator or the Responder.
Start | Message Type | Activity | Actor | State before | State after | Outcome |
---|---|---|---|---|---|---|
2 | Session Abort | sent by | Initiator | initiated |
aborted |
9-13 |
6 | Session Abort | sent by | Initiator | open |
aborted |
12, 13 |
9 | Session Abort | received by | Responder | (none) | aborted |
14 |
10 | Session Abort | received by | Responder | invited |
aborted |
14 |
11 | Session Abort | received by | Responder | declined |
declined |
14 |
12 | Session Abort | received by | Responder | open |
aborted |
14 |
13 | Session Abort | received by | Responder | aborted |
aborted |
14 |
When receiving a Session Abort
Message from the Initiator, the Responder's Session can be in one of the states listed in starting situations 9-13.
Some of these situations are actually "race conditions" that can occur due to asynchronous communication and the possibility of delayed or failed delivery of a previous Message. For instance, situation 9 depicts a case where the Responder receives the Session Abort
Message before even knowing about the Session. Situation 13 occurs if both VASPs have concurrently aborted the Session.
The receipt of a Session Abort
Message changes the Session's state to aborted
in all but one situation. The only exception is a Session in state declined
, which keeps its state. This rule ensures that the Responder's decision to decline before learning about the Initiator's attempt to abort the Session is put on record.
Start | Message Type | Activity | Actor | State before | State after | Outcome |
---|---|---|---|---|---|---|
4b | Session Abort | sent by | Responder | open |
aborted |
15-18 |
15 | Session Abort | received by | Initiator | initiated |
aborted |
19 |
16 | Session Abort | received by | Initiator | open |
aborted |
19 |
17 | Session Abort | received by | Initiator | closed |
closed |
19 |
18 | Session Abort | received by | Initiator | aborted |
aborted |
19 |
When receiving a Session Abort
Message from the Responder, the Initiator's Session can be in one of the states listed in starting situations 15-18. After the receipt, the state is changed to aborted
in all cases with exception of situation 16, where a Session in state closed
keeps its state.
Session Messages are a subset of Messages and therefore conformant with the interface description specified in 2.2 of this document. Additional attributes for the four Session Message types are hereinafter specified.
The Message must contain the following elements in its header
object:
Level 1 | Level 2 | Name | Type | Description |
---|---|---|---|---|
Header | ||||
Session identifier | session |
Hex(128-bit) | Randomly set | |
Message type | type |
String | Fixed value: 100 |
|
Ephemeral ECDH Public Key | ecdhpk |
Hex(33-Bytes) | Compressed Secp256k1 pubkey |
The Message must contain the following elements in its header
and body
objects:
Level 1 | Level 2 | Name | Type | Description |
---|---|---|---|---|
Header | ||||
Session identifier | session |
Hex(128-bit) | Value received in Session Request |
|
Message type | type |
String | Fixed value: 200 |
|
Ephemeral ECDH Public Key | ecdhpk |
Hex(33-Bytes) | Compressed Secp256k1 pubkey | |
Body | ||||
Return code | return |
String | See 4.2.1 |
Return Code | Meaning |
---|---|
1 |
Session accepted |
2 |
Session declined; Session Request not valid |
3 |
Session declined; Initiator declined |
4 |
Session declined; temporary disruption of service |
The Message must contain the following elements in its header
object:
Level 1 | Level 2 | Name | Type | Description |
---|---|---|---|---|
Header | ||||
Session identifier | session |
Hex(128-bit) | Value received in Session Request |
|
Message type | type |
String | Fixed value: 300 |
The Message must contain the following elements in its header
and body
objects:
Level 1 | Level 2 | Name | Type | Description |
---|---|---|---|---|
Header | ||||
Session identifier | session |
Hex(128-bit) | Value received in Session Request |
|
Message type | type |
String | Fixed value: 400 |
|
Body | ||||
Cause code | cause |
String | See 4.4.1 |
Cause Code | Meaning |
---|---|
1 |
Message acknowledgement timeout |
2 |
Session timeout |
3 |
Wrong or invalid message received |
4 |
Temporary disruption of service |
5 |
Unspecified |
Application
Structured interaction between VASPs for a dedicated purpose, e.g. agreeing on a virtual asset transfer and transmitting the related travel rule information. Defined by a set of Application Massages.
Application Message
Message with a defined set of elements to support the flow of Messages needed for an Application.
Each Application Message
must be conformant with the structure specified for all Messages in 2.2 of this document.
Each Application Message type must specify a unique message type to be set as value assigned to the type
element of the Message's header
object.
Specific elements of an Application Message must be part of the Message's body
object.
Application Messages must only be sent as part of a Session in state open
. The value assigned to the session
element of the header
object must be the value received in the Session Request
Message that initiated the Session.
The first Application Message within a Session must be sent by the Initiator.
The first Application Message sent within a Session defines the Application and the flow of subsequent Application Messages.
Edge Cases -- The protocol flow in the OpenVASP White Paper did not consider failure situations arising from unreliable communication.
Incomplete session state model -- No formal state model was specified for OpenVASP sessions, resulting in interoperability issues between different implementations.
Better Abstraction from transport layer -- In line with the ambition to allow for protocol implementation on top of different messaging systems, this OVIP better abstracts the specification of OpenVASP messages and the session model from actual implementations (e.g. Whisper).
Message Header -- New header
object streamlines meta data required in each message. The two-part structure of the message (content/signature) makes it clearer.
Session state model -- Suggested state model remains straightforward and close to the original proposal.
Session Aborts -- The ability to abort sessions was not available so far, but it was identified as an important feature to react to exceptions and operational issues.
The specification proposed in this OVIP is not backwards compatible.