Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.

Protocol

Christian Mayer edited this page Nov 4, 2014 · 35 revisions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Abstract

This document describes the basic communication for the network. It is written from the point of view of the implementor of a node.

Network Commands

The communication is based on the top of the Transmission Control Protocol. The default inbound port is 25000. Each node in the network should listen to the public on this port. The network uses DHT technics to distribute the contact informations about the nodes over the network.

Table of Contents

0. Keywords

  • Node: A node is a single instance on a PC or server in the network. A single node has an unique ID (or Node ID) in UUID5 format based on the public key.
  • Client: A client (or opposite node, or peer node) is always a single node connected via TCP connection to the local machine. The TCP connection can be inbound or outbound.

1. Identification

1.1. HELLO Command

This command is OPTIONAL but it's highly RECOMMENDED to be send after the TCP connection is established.

  • Arguments
    • (optional) ip: IP address of the opposite node.
  • Response: ID
  • Encryption: none

1.2. ID Command

Initialize a connection between two nodes on the Application Layer. It MUST be sent to establish a valid connection. Both nodes MUST send the ID command first of all on each new TCP connection. The opposite node SHOULD respond with ID_OK. This command is necessary to send further Network Commands. Optional the HELLO command can be sent before the ID command.

  • Arguments
    • (optional) release: Release number of PHPChat. For more anonymity don't send this field but it SHOULD be included. It's maybe necessary for future versions of PHPChat to make decisions to the behavior. In the standard case everything should be downward compatible.
    • id: ID of the local node in UUID5 format.
    • port: Inbound port of the local node.
    • sslKeyPub: Public key of the local node. Encoded in Base64.
    • sslKeyPubSign: SSL signature of the public key of the local node. Encoded in Base64.
    • (optional) isChannel: TRUE or FALSE. If a user wants do open a Talk inform the opposite user about the new connection. Otherwise set it to FALSE.
  • Response: ID_OK
  • Encryption: none

1.3. ID_OK Command

Response to the ID command.

  • Arguments: none
  • Response: none
  • Encryption: none

2. Node

2.1. NODE_FIND Command

Find a node by its ID.

  • Arguments
    • rid: A random Reference ID.
    • (optional) num: Amount of nodes to response. Default: Client::NODE_FIND_NUM
    • nodeId: The node ID to find. (UUID5)
    • hashcash: A new Hashcash.
  • Response: NODE_FOUND
  • Encryption: none

2.2. NODE_FOUND Command

This command will return one single node matching the exact node ID to find (NODE_FIND command) OR if the exact node ID can't be found in the table of the local node all nearby nodes to the node ID to find will be responded.

  • Arguments
    • rid: The Reference ID from the NODE_FIND command.
    • nodes array: Each entry MUST include an id (node ID), an uri and a sslKeyPub field of the found node(s).
    • hashcash: A new Hashcash.
  • Response: none
  • Encryption: none

3. Messages

In contrast to the live chat (or Talk) offline messages can be sent to a specified node.

  • If the destination node isn't known to the local node a NODE_FIND command will be sent to the network first.
  • If the destination node is online the message will be transmitted peer-to-peer.
  • If the destination node isn't online the message will be transmitted through other nodes. The network will then try to deliver the message.

Only the destination node can decrypt and read the message.

A message will be created as follows:

  1. Generate a 2048-bit long random password.
  2. Sign the password with the private key of the source node.
  3. Encrypt the password with the public key of the destination node.
  4. Sign the text with the private key of the source node.
  5. Encrypt the body of the message with the password in AES-256-CBC mode.

New Message Flowchart

3.1. MSG Command

  • Arguments
    • rid: A random Reference ID.
    • version: Version number of the message. Current: 1
    • id: The ID of the message.
    • srcNodeId: Source node ID.
    • srcSslKeyPub: Public key of the source node.
    • dstNodeId: Destination node ID.
    • body: Encrypted body in Base64 format.
    • password: Encrypted password.
    • checksum: Checksum of the message.
    • relayCount: A message can be relayed through one or more nodes. Each node should increase the relayCount field by one for each message.
    • timeCreated: The creation time of the message in unix time format (seconds since 01/01/1970).
    • hashcash: A new Hashcash.
  • Response: MSG_RESPONSE
  • Encryption: none

3.2. MSG_RESPONSE Command

The receiving node of a MSG command SHOULD respond with a MSG_RESPONSE command.

  • Arguments
    • rid: The Reference ID from the MSG command.
    • status:
      • 1: Ok. Message is new and will be saved.
      • 2: Reject. Message already known.
      • 3: Error. Something is wrong.
  • Response: none
  • Encryption: none

4. SSL

4.1. SSL_INIT Command

To send further SSL encrypted Network Commands both nodes must begin the SSL initialization with this command. Both nodes MUST begin the SSL initialization with the SSL_INIT command and MUST respond in the correct order to all commands from the opposite node.

  • Arguments
    • hashcash: A new Hashcash.
  • Response: SSL_INIT_RESPONSE
  • Encryption: none

4.2. SSL_INIT_RESPONSE Command

  • Arguments
    • status:
      • 1: Ok. Node is comfortable to continue the SSL initialization.
      • >=1000: Error.
  • Response: SSL_TEST
  • Encryption: none

4.3. SSL_TEST Command

To test the public-key encryption the opposite node MUST response the correct token from the SSL_TEST command with the SSL_VERIFY command.

  • Arguments
    • token: Random UUID.
  • Response: SSL_VERIFY
  • Encryption: public-key

4.4. SSL_VERIFY Command

  • Arguments
    • token: The token from the SSL_TEST command.
  • Response: SSL_PASSWORD_PUT
  • Encryption: public-key

4.5. SSL_PASSWORD_PUT Command

To encrypt/decrypt a Network Command with password(s) see 4.11. Symmetric Encryption/Decryption for more information.

  • Arguments
    • password: The password from the local node.
  • Response: SSL_PASSWORD_TEST
  • Encryption: public-key

4.6. SSL_PASSWORD_TEST Command

To test both passwords each node must generate a random Password Token.

  • Arguments
    • token: Random UUID.
  • Response: SSL_PASSWORD_VERIFY
  • Encryption: symmetric

4.7. SSL_PASSWORD_VERIFY Command

4.7.1. SSL_PASSWORD_VERIFY Basic
  • Arguments
    • token: See 4.7.2. SSL_PASSWORD_VERIFY Procedure.
  • Response: none
  • Encryption: symmetric
4.7.2. SSL_PASSWORD_VERIFY Procedure

Each node must respond with a new generated token to the SSL_PASSWORD_TEST command.

Procedure for each node:

  1. Concatenate the token from the SSL_PASSWORD_TEST command, a unterscore (_) and the local node ID.
    For example: $basic = $peerNodeToken.'_'.$localNodeId;
  2. Generate a SHA512 hex string from the string in step 1.
    For example: $token = hash('sha512', $basic);
  3. Send the generated SHA512 hex string (token) to the opposite node.
  4. The opposite node must generate the same token locally and compare it with the received token.
  5. If the tokens are correct the SSL connection is established.

4.8. SSL_PASSWORD_REPUT Command

After some time elapsed OR when some amount of encrypted messages were sent each node can (for more security it SHOULD) send a SSL_PASSWORD_REPUT command. This is nearly the same procedure as SSL_PASSWORD_PUT, SSL_PASSWORD_TEST and SSL_PASSWORD_VERIFY but not based on the public-key encryption but on the existing passwords. For this steps each node needs two more variables in addition to the current local password and the current peer password: the new local password and the new peer password.

  • Arguments
    • password: The new password from the local node.
  • Response: SSL_PASSWORD_RETEST
  • Encryption: symmetric

4.9. SSL_PASSWORD_RETEST Command

Also see 4.6. SSL_PASSWORD_TEST Command.

  • Arguments
    • token: Random UUID.
  • Response: SSL_PASSWORD_REVERIFY
  • Encryption: symmetric

4.10. SSL_PASSWORD_REVERIFY Command

Also see 4.7. SSL_PASSWORD_VERIFY Command. If the tokens are verified the old local and peer password can be deleted and the new passwords MUST be used instead of the old ones.

  • Arguments
    • token
  • Response: none
  • Encryption: symmetric

4.11. Symmetric Encryption/Decryption

To enable the symmetric encryption/decryption two passwords are needed. Both nodes (the local node and the opposite node) must generate a 1024-bit long random password and send it to the opposite node (a.k.a. peer node). Each node must store the local password ($sslPasswordLocal) and the peer password ($sslPasswordPeer) in memory to the end of each SSL session.

Password for encryption:

$password = $sslPasswordLocal.'_'.$sslPasswordPeer;

Password for decryption:

$password = $sslPasswordPeer.'_'.$sslPasswordLocal;

5. Talk

A peer-to-peer live chat is called Talk. To enable a Talk a SSL connection (see 4. SSL) is required.

5.1. TALK_REQUEST Command

To establish a talk a Talk Request is required. The opposite node must be able to respond to a Talk Request. After some time elapsed (TTL) a Talk Request can expire if the opposite node doesn't respond.

  • Arguments
    • rid: A random Reference ID.
    • (optional) userNickname: The nickname of the local user.
    • hashcash: A new Hashcash.
  • Response: TALK_RESPONSE
  • Encryption: symmetric

5.2. TALK_RESPONSE Command

If a Console is connected to the Kernel the user can accept or decline a Talk Request. If the user accepts a Talk Request the other user will be added to the Addressbook and both user switch to the live chat on the console. If no console is connected to the Kernel the node immediately respond with Status 4. If nothing happens the node will respond with Status 3. There is also a local TTL for each Talk Request.

  • Arguments
    • rid: The Reference ID from the TALK_REQUEST command.
    • status:
      • 1: Accept.
      • 2: Decline.
      • 3: Timeout.
      • 4: No console.
    • (optional) userNickname: The nickname of the local user.
  • Response: TALK_RESPONSE
  • Encryption: symmetric

5.3. TALK_MSG Command

A single message of a Talk.

  • Arguments
    • (optional) rid: A random Reference ID.
    • (optional) userNickname: The nickname of the local user. It's RECOMMENDED to send a nickname.
    • text: User text.
    • ignore: To ensure more anonymity random Talk Messages will be sent during an open Talk. If the ignore field is TRUE the recipient node MUST ignore this Talk Message because its text is only random. Random length and sent in random intervals.
  • Response: none
  • Encryption: symmetric

5.4. TALK_USER_NICKNAME_CHANGE Command

If a user changes the nickname during a Talk this command can be sent to notify the opposite node about the change.

  • Arguments
    • (optional) userNicknameOld: The old user nickname.
    • userNicknameNew: The new user nickname.
  • Response: none
  • Encryption: symmetric

5.5. TALK_CLOSE Command

Close a Talk. Also closes the TCP connection.

  • Arguments
    • (optional) rid: A random Reference ID.
    • (optional) userNickname: The nickname of the local user.
  • Response: none
  • Encryption: symmetric

6. Connection

6.1. PING Command

Ping pong to keep the connection alive. The opposite node MUST respond with a PONG command. If a opposite node doesn't respond to a ping the connection will be closed after some time elapsed.

  • Arguments
    • (optional) rid: A random Reference ID.
  • Response: none
  • Encryption: none

6.2. PONG Command

  • Arguments
    • (optional) rid: The Reference ID from the PING command.
  • Response: none
  • Encryption: none

6.3. QUIT Command

End a connection. The TCP connection will be closed by each node.

  • Arguments: none
  • Response: none
  • Encryption: none

7. Bridge

BRIDGE IS NOT IMPLEMENTED YET

8. Error

8.1 ERROR Command

If an error occurs to a node this command can be send to the opposite node.

  • Arguments
    • code: Number from 1000 to 9999. See Client.php, getError() for more informations.
    • (optional) msg: Text of the error.
    • name: Name of the Network Command.
  • Response: none
  • Encryption: none

Appendix

A. Creating a Network Message

A Network Message is based on strings. Means: no binary formats are used to build a Network Message. Only JSON and Base64 are used to create a socket packet. Network Messages are seperated by a New Line Character, ASCII code 10.

Step by step:

  1. Create an associative array with a name and a data key. The value of the name key must be filled with one name from the Network Commands. For some commands the data field is optional.
    Example code: $ar = array('name' => 'hello');
    The data field is an array with the arguments for each command.
    Example code: $ar = array('name' => 'hello', 'data' => array('ip' => '192.168.241.21'));
  2. Encode the array to a JSON string. For example: {"name":"hello"}
  3. Encode this string with Base64. For example: eyJuYW1lIjoiaGVsbG8ifQ==
  4. Add a newline character (\n --- ASCII code 10) to the end of the string. The Client-class provides the MSG_SEPARATOR constant. For example: eyJuYW1lIjoiaGVsbG8ifQ==\n
  5. Send the string to the opposite node.

B. Reference ID

In some cases the requester needs a Reference ID (or rid) to assign the request to the response. In such cases a Reference ID must be send in the request message and in the response message. This SHOULD be a UUID.

C. Proof-of-work

Hashcash is used for proof-of-work.

Clone this wiki locally