zetok / tox

toxcore implementation in Rust. Codename zetox.

Home Page:https://zetok.github.io/tox

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

root: TCP relay server

zetok opened this issue · comments

commented

https://zetok.github.io/tox-spec/#tcp-server

Everything for server is done except for Onion packets.

  • Onion packets parsing #99
  • Onion packets nop-handling (it is possible for tcp relay to ignore Onion packets)
  • Onion packets handling

Packet parsing

  • | handshake |
  • | 0x0 | RouteRequest
  • | 0x1 | RouteResponse
  • | 0x2 | ConnectNotification
  • | 0x3 | DisconnectNotification
  • | 0x4 | PingRequest
  • | 0x5 | PongResponse
  • | 0x6 | OobSend
  • | 0x7 | OobReceive
  • | 0x8 | OnionDataRequest
  • | 0x9 | OnionDataResponse
  • | 0x10 - 0xF0 | Data

Logic

  • | handshake |
  • | 0x0 | RouteRequest
  • | 0x1 | RouteResponse
  • | 0x2 | ConnectNotification
  • | 0x3 | DisconnectNotification
  • | 0x4 | PingRequest
  • | 0x5 | PongResponse
  • | 0x6 | OobSend
  • | 0x7 | OobReceive
  • | 0x8 | OnionDataRequest
  • | 0x9 | OnionDataResponse
  • | 0x10 - 0xF0 | Data

Network

  • | handshake |
  • | 0x0 | RouteRequest
  • | 0x1 | RouteResponse
  • | 0x2 | ConnectNotification
  • | 0x3 | DisconnectNotification
  • | 0x4 | PingRequest
  • | 0x5 | PongResponse
  • | 0x6 | OobSend
  • | 0x7 | OobReceive
  • | 0x8 | OnionDataRequest
  • | 0x9 | OnionDataResponse
  • | 0x10 - 0xF0 | Data
commented

I reverse engineered TCP handshake. Here it is.

pk = public key
sk = secret key

TCP handshake

1. Client:

Has:

* client_pk
* client_sk
* server_pk

Computes and Stores:

* client_sent_nonce = random nonce()

Computes:

* shared_key = encrypt_precompute(server_pk, client_sk)
* (temp_client_pk, temp_client_sk) = crypto_box_keypair()

Stores:

* temp_client_sk

Computes:

* payload = [temp_client_pk, client_sent_nonce]

* nonce = random nonce()
* encrypted_payload = encrypt_data_symmetric(shared_key, nonce, payload)
* handshake_packet = [client_pk, nonce, encrypted_payload]

Sends:

* handshake_packet

By now client has:
* server_pk
* client_pk
* client_sk
* client_sent_nonce
* temp_client_sk
2. Server:

Receives:

* handshake_packet

Has:

* server_pk
* server_sk

Computes and Stores:

* server_sent_nonce = random nonce()

Computes:

* [client_pk, nonce, encrypted_payload] = handshake_packet
* shared_key = encrypt_precompute(client_pk, server_sk)
* payload = decrypt_data_symmetric(shared_key, nonce, encrypted_payload)

* [temp_client_pk, server_recv_nonce=client_sent_nonce] = payload

* (temp_server_pk, temp_server_sk) = crypto_box_keypair()
* common_shared_key = encrypt_precompute(temp_client_pk, temp_server_sk)

Stores:

* server_recv_nonce
* common_shared_key
* client_pk

Computes:

* payload = [temp_server_pk, server_sent_nonce]
* nonce = random nonce()
* encrypted_payload = encrypt_data_symmetric(shared_key, nonce, payload)

* handshake_packet = [nonce, encrypted_payload]

Sends:

* handshake_packet


By now server has:

* client_pk
* server_pk
* server_sk
* server_sent_nonce
* server_recv_nonce
* common_shared_key
3. Client:

Receives:

* handshake_packet

Computes:

* shared_key = encrypt_precompute(server_pk, client_sk)
* [nonce, encrypted_payload] = handshake_packet
* payload = decrypt_data_symmetric(shared_key, nonce, encrypted_payload)

* [temp_server_pk, client_recv_nonce=server_sent_nonce] = payload

* common_shared_key = encrypt_precompute(temp_server_pk, temp_client_sk)


Stores:

* client_recv_nonce
* common_shared_key

Removes:

* temp_client_sk

By now client has:
* server_pk
* client_pk
* client_sk
* client_sent_nonce
* client_recv_nonce
* common_shared_key

TCP Communication

Client:

1.

encrypted = encrypt_data_symmetric(common_shared_key, client_sent_nonce, data)
send(encrypted)
increment_nonce(client_sent_nonce) if could encrypt and send

Server:

2.

receive(encrypted)
data = decrypt_data_symmetric(common_shared_key, server_recv_nonce, encrypted)
increment_nonce(server_recv_nonce) if could receive and decrypt

3.

encrypted = encrypt_data_symmetric(common_shared_key, server_sent_nonce, data)
send(encrypted)
increment_nonce(server_sent_nonce) if could encrypt and send

Client:

4.

receive(encrypted)
data = decrypt_data_symmetric(common_shared_key, client_recv_nonce, encrypted)
increment_nonce(client_recv_nonce) if decrypted if could receive and decrypt

commented

Handshake

            PK + PublicKey
            SK + SecretKey
            PcK + PrecomputedKey

               Client                                   Network                             Server
+----------------------------------------------------------+----------------------------------------------------------------------+
       +----------------------+                            |                       +----------------------+
       | crypto_box_keypair() |                            |                       | crypto_box_keypair() |
       +----+-------------+---+                            |                       +----+-------------+---+
            |             |                                |                            |             |
    +-------v----+    +---v--------+                       |                    +-------v----+    +---v--------+
  +-+ Session SK |    | Session PK +-----+                 |               +----+ Session PK |    | Session SK +---------------------+
  | +------------+    +------------+     |                 |               |    +------------+    +------------+                     |
  |        +--------------+              |                 |               |           +--------------+                              |
  |        |  new nonce() |              |                 |               |           |  new nonce() |                              |
  |        +------+-------+              |                 |               |           +------+-------+                              |
  |               |                      |                 |               |                  |                                      |
  |      +--------v--------+             |                 |               |         +--------v--------+                             |
  |      |client_sent_nonce|             |                 |               | +-------+server_sent_nonce|                             |
  |      +-----+-----------+             |                 |               | |       +-----------------+                             |
  |            |                         |                 |               | |                                                       |
  |            |                         |  +------------+ |               | |          +------------+                               |
  |            | +-----------------+     |  | Server PK  | |               | |          | Server SK  +-------------------+           |
  |     +--------+Payload          |     |  +--+---------+ |               | |          +------------+                   |           |
  |     |      | +-----------------+     |     |           |               | |                                           |           |
  |     |      | |Session PK       <-----+     |           |               | |                                           |           |
  |     |      | +-----------------+           |           |               | |                                           |           |
  |     |      +->client_sent_nonce|           |           |               | |        +-----------------+                |           |
  |     |        +-----------------+           |           |       +------------------>Packet           |                |           |
  |     |            +--------------+          |           |       |       | |        +-----------------+           +----v--------+  |
  |     |            |  new nonce() |          |           |       |       | |        |Client PK        +----------->precomputed()|  |
  |     |            +-------+------+          |           |       |       | |        +-----------------+           +----+--------+  |
  |     |                    |                 |           |       |       | |    +---+Nonce            |                |           |
  |     |            +-------v------+          |           |       |       | |    |   +-----------------+             +--+----+      |
  |     |    +-------+   Nonce      +---------------+      |       |       | |    |   |Encrypted Payload|  +----------+  PcK  |      |
  |     |    |       +--------------+          |    |      |       |       | |    |   +----------+------+  |          +--+----+      |
  |     |    |   +------------+  +----------+  |    |      |       |       | |    |              |         |             |           |
  |     |    |   | Client SK  |  |Client PK +---------+    |       |       | |    |         +----v---------v---+         |     +-----v------+
  |     |    |   +-------+----+  +----------+  |    | |    |       |       | |    +--------->open_precomputed()|         |  +-->precompute()|
  |     |    |           |                     |    | |    |       |       | |              +--------+---------+         |  |  +-----+------+
  |     |    |           +--------------+      |    | |    |       |       | |                       |                   |  |        |
  |     |    |                          |      |    | |    |       |       | |              +--------v--------+          |  |  +-----v-----------+
  |     |    |                          |      |    | |    |       |       | |              |Payload          |          |  |  |Session PcK      |
  |     |    |   +-------+         +----v------v-+  | |    |       |       | |              +-----------------+          |  |  +-----------------+
  |     |    |   |  PcK  <---------+precomputed()|  | |    |       |       | |              |Session PK       +-------------+
  |     |    |   +-+---+-+         +-------------+  | |    |       |       | |              +-----------------+          |     +-----------------+
  |     |    |     |   |                            | |    |       |       | |              |client_sent_nonce+---------------->server_recv_nonce|
  |     |    |     |   +-----+                      | |    |       |       | |              +-----------------+          |     +-----------------+
  |     |    |     |         |                      | |    |       |       | |                                           |
  |     |    |     |  +------v------------+         | |    |       |       | |                 +--------------+          |
  |     +------------->seal_precomputed() <---------+ |    |       |       | |                 |  new nonce() |          |
  |          |     |  +---------+---------+           |    |       |       | |                 +-------+------+          |
  |          |     |            |                     |    |       |       | |                         |                 |
  |          |     |            |                     |    |       |       | |                 +-------v------+          |
  |          |     |   +--------v--------+            |    |       |       | |         +-------+   Nonce      +---------------+
  |          |     |   |Encrypted Payload+------+     |    |       |       | |         |       +--------------+          |    |
  |          |     |   +-----------------+      |     |    |       |       | |         |                                 |    |
  |          |     |                            |     |    |       |       | |         |                                 |    |
  |          |     |   +-----------------+      |     |    |       |       | |         |       +------------------+      |    |
  |          |     |   |Packet           +-------------------------+       | |         |       |Payload           +-+    |    |
  |          |     |   +-----------------+      |     |    |               | |         |       +------------------+ |    |    |
  |          |     |   |Client PK        <------------+    |               +------------------->Session PK        | |    |    |
  |          |     |   +-----------------+      |          |                 |         |       +------------------+ |    |    |
  |          +--------->Nonce            |      |          |                 +----------------->server_sent_nonce | |    |    |
  |                |   +-----------------+      |          |                           |       +------------------+ |    |    |
  |                |   |Encrypted Payload<------+          |                           |                +-----------+    |    |
  |                |   +-----------------+                 |                           |                |                |    |
  |                |                                       |                           |       +--------v---------+      |    |
  |                |   +-----------------+                 |                           +------->seal_precomputed()<------+    |
  |           +----+   |Packet           <--------------------------+                          +--------+---------+           |
  |           |        +-----------------+                 |        |                                   |                     |
  |           |  +-----+Nonce            |                 |        |                          +--------v---------+           |
  |           |  |     +-----------------+                 |        |                          |Encrypted Payload +----+      |
  |           |  | +---+Encrypted Payload|                 |        |                          +------------------+    |      |
  |           |  | |   +-----------------+                 |        |                                                  |      |
  |   +-------v--v-v-----+                                 |        |                          +------------------+    |      |
  |   |open_precomputed()|                                 |        +--------------------------+Packet            |    |      |
  |   +---------+--------+                                 |                                   +------------------+    |      |
  |             |                                          |                                   |Nonce             <-----------+
  |             +---------------+                          |                                   +------------------+    |
  |                    +--------v--------+                 |                                   |Encrypted Payload <----+
  |                    |Payload          |                 |                                   +------------------+
  |                    +-----------------+                 |
  +------------+   +---+Session PK       |                 |
               |   |   +-----------------+                 |
               |   |   |server_sent_nonce+----+            |
               |   |   +-----------------+    |            |
               |   |                          |            |
               |   |                          |            |
           +---v---v----+                     |            |
           |precompute()|               +-----+            |
           +-----+------+               |                  |
                 |                      |                  |
           +-----v------+      +--------v--------+         |
           |Session PcK |      |client_recv_nonce|         |
           +------------+      +-----------------+         |
                                                           |
  +--------------------------------------------------------+--------------------------------------------------------------------------+