TSK management

TSK is a temporary symmetric session key generated by the server and used to EtA session commands and results, this way the tranmassion could not be neither spied not tampered even over clear connections or borken https. The TSK key could be dropped by the server at any time without notification so client software implementing session command interfaces should be ready tore-establish session (see "flow") at any moment. Also note that the session does not carry nessun state other than the SCK/TSK pair and is used solely to protect client-server communication.

The important difference with TSK is that client should check the saved TSK that can be valid, invalid and has expiration time. When the TSK is about to expore, the client software maigh want to refresh it before the service will reject session command. Also, it is a goo idea to save in local storage last known expiration date for the TSK key and recreate if need skipping check.

Check TSK key

This is a session_comand - it should be issued to a session endpoint.

getSessionInfo() -> 
    { 
        expiresAt: Date,
        isTest: boolean
    }

If the TSK used to encrypt session command is still valid, the successful result will be returned. Any remote error means that the TSK is no longer valid. It does not apply to network errors, so check error types and codes.

Note that session expiration could change with time. It's up to service logic to extend service lifespan, for example, if the session is actively used and usage pattern are regular, or kill the session if the activity is suspicios, aggressive to the service or session semms to be abandoned. This will make aggressor to spend most of the time on solving POW task rather than attacking the service, and the service is free to increase POW complexity, for example, fo suspicious IP address groups, not blocking them completely, but selective complicating attacking from it.

Create TSK key

Use to create new key or refresh existing one. Client must have registered SCK. If there was TSK key geberated for the session, it will be iinvalidated. This is a guest command supported by a root connection.

createTSK(signedRecord: requestRecord) -> 
    { encryptedSignedRecord: Uint8Array }

The requestRecord is a SignedRecord created with SCK and comtaining the following payload:

{
    clientNonce: Uint8Array,       // random bytes to check service authentity
    sessionId: string,             // returned when registering SCK
    knownServiceKeys: Uint8Array[] // list of service key addresses known to client
}

The knownServiceKeys should contain list of service keys address knwon to the caller from source that depends on parsec version. It could be a pre-shared public key (1.1), preshared service contract, which could be checked against the blockchain then used to extract actual service keys, or UNS2 contract that could be obtained from the Universa network and then used to extract service keys the same way.

Important, that if the service responds with error with code unknown_service_key the client should refresh its source and try to obtain up-to-date service key addresses. Parsec1.* connections are not available if the client has no source of service authentication!

If everything is ok, service responds with signed record with encrypted data:

{ 
  signedEncryptedResult: Uint8Array  
}

First, client unpacks the signed record, ensure it is signed with one of the keys it has requested, and contains valid payload:

{
    clientNonce: Uint8Array,        // should be equal to requested
    encryptedResult: Uint8Array     // encrypted answer
}

Important. Client mustn't attempt to decrypt encryptedResult prior to checking clientNonce. If the nonce is valid, and signed with valid service key, it is safe to decrypt the encypted result. Otherwise, the data are from unknown and untrusted source and should be completely ignored. With parsec 1.2 and 1.3 client should reacquire service contract and check ut, or just relaod UNS2 contract from the network, it might have updated information and the old key/domain could be squatted or somehow else compromized.

Client decrypt result with its CSK and unpacks it with BOSS, getting the result:

{
    TSK: Uint8Array,     // binary TSK key itself
    TSKExpiresAt: Date,  // current key expration
}

Expiratin may change with time, and the key could be cancelled at any moment by the service and/or client, so client sofwatre should track the error codes while execute commands in session and regenerate TSK or reestablish the session as shown on the diagram above.

Where TSK is a SymmetricKey to use with. Note that encryption here uses UniversalPublicKey encrypted data format which is more effective and allow encrypt any size data optimally using the key size and extending it with symmetric encryption block as need.

Regenerating TSK

Create new TSK key at any time, as described above. It cleares existing TSK key if it exsted.