QuickTunTcp
Jump to navigation
Jump to search
Protocol
General packet format: 2 bytes, 16 bits big endian integer, packet length/flags bit 15: most significant bit: 0=tunnel data, 1=control command bit 14-0: payload length (max 32kB payload) "length" bytes, payload if encryption has been enabled, the entire payload is encrypted, otherwise it is in plain text Control command (inner format): 1 byte, Control command code Control arguments General protocol operation: The protocol starts operation in unsecure mode. Either side can initiate an encrypted connection using the "Start crypto auth" control command, optionally followed by "Begin key update" to enable the use of session keys for PFS. Either side can request password based authentication from the other side by sending the "Start password authentication" control command. If the encryption keys are to be used only for authentication but not for data encryption, either side can request to disable further encryption using the "Disable encryption" control command. Both sides of the connection start operation with a documented, hard coded key pair for both the local and remote side, and the nonce buffer set to all zero. This provides correct operation during the initial key exchange, these keys should not be used for security and no secret data should be transfered while these keys are in use. If encryption is enabled, after a packet is encrypted, the 24 byte (send) nonce is incremented as a big-endian number. Control commands: 0 Start tunnel data Sent after initial negotiation has been completed, to indicate that the current state of the tunnel is acceptable to the sender (in terms of security and configuration) and the remote side may enable the tunnel and start sending data When either side has both sent and received this command, it should enable the tunnel and start sending data 1 Start crypto auth - Public key (32 bytes) - Nonce bytes (24 bytes) This command informs the other side of the intention to enable encryption and to provide the sender's public key and randomly generated nonce initialization data. If the remote side is supposed to know the local public key (from its configuration, in a 1-to-1 connection), the public key may be set to all zero and should be ignored by the remote side. The remote side may use the Public key value provided for authentication purposes (accepting/rejecting the connection or selecting a client specific configuration). After this command has been sent, all outgoing packets are also encrypted. If no key is known for the remote system, a fixed key is used until the remote key is known. The nonce for outgoing packets is constructed as follows: remotenonceinput[0:12]+localnonceinput[0:12] 2 Acknowledge crypto auth - Public key (32 bytes) - Nonce bytes (24 bytes) This command is sent in response to a "Start crypto auth" command, to provide the remote side with the sender's public key and randomly generated nonce initialization data. The remote side may use the Public key value provided for authentication purposes (accepting/rejecting the connection or selecting a client specific configuration). After this command has been sent, all outgoing packets are also encrypted. The nonce for outgoing packets is constructed as follows: remotenonceinput[0:12]+localnonceinput[0:12] 3 Begin key update - Public key (32 bytes) This command informs the remote side of an updated local key. After this command has been sent, all outgoing packets are also encrypted. 4 Acknowledge key update This command informs the remote side that the key update has been received and the new key will be used for following outgoing packets. After this command has been sent, all outgoing packets are also encrypted. 5 Start password authentication - Salt (variable length) Requests the remote side to authenticate with a password, using the "Acknowledge password authentication" command, providing a salt value for the hash operation. 6 Acknowledge password authentication - Hashed password (512 bits) Authenticates to the remote side using a password, in response to the "Start password authentication" command. The "Hashed password" is formed as sha512(Salt + Password) where Password is an ASCII or UTF-8 encoded string. 7 Disable encryption Requests the remote side to disable encryption. This can be useful if the encryption keys are used only for authentication. After this command has been sent, all outgoing packets are no longer encrypted. The remote side may close the connection if this is unacceptable. 8 Acknowledge disable encryption Confirms that the request to disable encryption has been received. After this command has been sent, all outgoing packets are no longer encrypted. 9 Echo request - Data (variable length) Requests the remote side to echo the data back. This can be used to test latency or check whether the connection is still alive. 10 Echo response - Data (variable length) Response to the "Echo request" command. - Other control commands can be added later for automatic IP configuration and other uses Example control flows: Raw mode VPN A Start tunnel data B Start tunnel data VPN traffic Password authenticated VPN A Start tunnel data B Start password authentication A Acknowledge password authentication B Start tunnel data VPN traffic Mutual password authenticated VPN A Start password authentication B Start password authentication B Acknowledge password authentication A Acknowledge password authentication B Start tunnel data A Start tunnel data - VPN traffic Encrypted public VPN A Start tunnel data B Start crypto auth A Acknowledge crypto auth A Begin key update (keySA1->keyB) B Begin key update (keyB->keySA1) B Acknowledge key update (keySB1->keySA1) A Acknowledge key update (keySA1->keyB) B Start tunnel data (keySB1->keySA1) - VPN traffic (keySA1<->keySB1) * Since A has no fixed key, it uses a randomly generated key during initial crypto negotiation. This makes the "Begin key update" initiated by A redundant - it is not needed but accepted to simplify implementations. B chose to use a session key, but it could have used its fixed key for the entire conversation if PFS is not required. In this case the key update initiated by B would have been redundant as well. * keySA1 is the first session key used by A, keyB is the fixed key configured on B, keySB1 is the first session key used by B Encrypted public VPN with password authentication A Start tunnel data B Start crypto auth A Acknowledge crypto auth B Start password authentication (keyB->keySA1) A Acknowledge password authentication (keySA1->keyB) B Begin key update (keyB->keySA1) A Acknowledge key update (keySA1->keyB) B Start tunnel data (keySB1->keySA1) - VPN traffic (keySA1<->keySB1) * The order of password authentication and key updates is arbitrary. The protocol allows password authentication and key exchanges to be initiated at any point in the connection. Encrypted authenticated VPN A Start crypto auth B Start crypto auth A Acknowledge crypto auth (keyA->key0) B Acknowledge crypto auth (keyB->key0) A Begin key update (keyA->keyB) B Begin key update (keyB->keyA) A Acknowledge key update (keySA1->keyB) B Acknowledge key update (keySB1->keyA) A Start tunnel data (keySA1->keySB1) B Start tunnel data (keySB1->keySA1) - VPN traffic (keySA1<->keySB1) A Begin key update (keySA1->keySB1) A VPN traffic (keySA2->keySB1) B VPN traffic (keySB1->keySA1) B Acknowledge key update (keySB1->keySA1) - VPN traffic (keySA2<->keySB1) * keyA and keyB are the fixed keys configured at A and B respectively, key0 is the fixed documented key (see General protocol operation), keySA1 and keySB1 are the first session keys generated by A and B respectively, keySA2 is the second seccion key generated by A Cryptographically authenticated unencrypted VPN A Start crypto auth B Start crypto auth A Acknowledge crypto auth (keyA->key0) B Acknowledge crypto auth (keyB->key0) A Disable encryption (keyA->keyB) B Acknowledge disable encryption (keyB->keyA) - VPN traffic