QuickTunTcp

From Qontrol.nl Wiki
Jump to: navigation, search

Protocol

General packet format:
	2 bytes, 16 bits big endian integer, packet length/flags
		bit 0: most significant bit: 0=tunnel data, 1=control command
		bit 1-15: 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]
		On reception of this command, a "Acknowledge crypto auth" message should be sent in return. Additionally, a "Start crypto auth" or "Begin key update" message should be sent by the recipient, if it has not already done so.
	2	Acknowledge crypto auth
		This command is sent in response to a "Start crypto auth" command, to confirm that the key update has been received and the new key will be used to encrypt packets from this point on.
		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.
	11	Set network configuration
		- IP or Ethernet mode
		- IPv4 address and network mask, IPv4 peer address and network mask, IPv4 DNS server
		- IPv6 address and network mask, IPv6 peer address and network mask, IPv6 DNS server
		This allows a server to automatically assign IP addresses to clients. A client may choose to ignore this message.
	12	Routing information update
		- Address family (Ethernet, IPv4, IPv6; defines size of Network address and mask)
		- Valid flag
		- Network address and mask
		- List of 4 byte AS numbers or other identification
		This command provides basic routing information exchange, which can be used to create a routable mesh network. The command uses a mechanism similar to the BGP protocol and as such might be linked to a BGP router.
	13	Data packet
		- Data
		This command can be used to include data packets in the control stream. This is useful when the packet type needs to be hidden in an encrypted connection, or when padding or combining of small packets is desirable (see the next few commands).
	14	Padding
		- Padding size (1 byte)
		- Control packet
		This message contains another control message, with the specified amount of padding data appended at the end (which should be discarded). This can be used to hide the actual length of the packet from attackers. Padding messages can be nested to add more than 255 bytes of padding, but should not be nested more than approximately 10 levels so that an application can use a recursive algorithm to process such packets.
	15	Multiple messages
		- 16 bits big endian integer, inner message length
		- Inner message data
		- repeat...
		This command can be used to combine multiple (small) control messages into one packet. Intended use is to allow minimization of cryptographic overhead. This message can be nested.
	17	Tunnel options
		- 1 bit: encryption supported
		- 1 bit: unencrypted data allowed
		- 6 bits: reserved
		This command should be sent when a connection is established, to inform the other side of the ability to handle encryption and acceptability of unencrypted data transfer. The remote side can use this to determine whether it's acceptable to ask for encryption or to disable encryption (if such is allowed by the local configuration). If support for encryption is not indicated and a request for enabling encryption is received, the connection may be closed.
	81
		- ASCII "UICKTUN"
		This command should be the first to be sent by a client once the connection is established. A server may also send this command. The intended use of this command is to provide identification of the protocol if a port is shared by multiple servers (eg VPN, SSH and HTTPS running on port 443). The protocol can be identified by the byte sequence (hex): 80 08 51 55 49 43 4B 54 55 4E.
	-
		Other control commands can be added later for automatic IP configuration and other uses

Example control flows:
	Raw mode VPN
	A	Start tunnel data -- A requires no more negotiation and is ready to go
	B	Start tunnel data -- B requires no more negotiation and is ready to go
		VPN traffic

	Password authenticated VPN
	A	Start tunnel data -- A requires no more negotiation and is ready to go
	B	Start password authentication -- B would like to see password authentication first
	A	Acknowledge password authentication -- A authenticates with password
	B	Start tunnel data -- B is happy, the tunnel can be started
		VPN traffic

	Mutual password authenticated VPN
	A	Start password authentication -- A would like to see password authentication
	B	Start password authentication -- B would like to see password authentication
	B	Acknowledge password authentication -- B authenticates with password, as requested by A
	A	Acknowledge password authentication -- A authenticates with password, as requested by B
	B	Start tunnel data -- B is happy
	A	Start tunnel data -- A is happy, the tunnel can be started
	-	VPN traffic

	Encrypted public VPN
	A	Start tunnel data -- A requires no more negotiation and is ready to go
	B	Start crypto auth -- B requires encryption to be enabled and sends keyB and nonce initialization, following outgoing communication will be encrypted keyB->key0
	A	Acknowledge crypto auth -- A confirms the request, following outgoing communication will be encrypted key0->keyB
	A	Begin key update (key0->keyB) -- A generates a session key keySA1 and sends to B, following outgoing communication will be encrypted keySA1->keyB
	B	Begin key update (keyB->key0) -- B likes PFS and also generates a session key keySB1, following outgoing communication will be encrypted keySB1->key0
	B	Acknowledge key update (keySB1->key0) -- B confirms reception of the request, following outgoing communication will be encrypted keySB1->keySA1
	A	Acknowledge key update (keySA1->keyB) -- A confirms reception of the request, following outgoing communication will be encrypted keySA1->keySB1
	B	Start tunnel data (keySB1->keySA1) -- B is happy, the tunnel can be started
	-	VPN traffic (keySA1<->keySB1)
	* 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.
	* key0 is the fixed well-known key documented above, keyB is the fixed key configured on B, keySA1 and keySB1 are the first session keys generated by A and B respectively.

	Encrypted public VPN with password authentication
	A	Start tunnel data -- A requires no more negotiation and is ready to go
	B	Start crypto auth -- B requires encryption to be enabled and sends keyB and nonce initialization, following outgoing communication will be encrypted keyB->key0
	A	Acknowledge crypto auth -- A confirms the request, following outgoing communication will be encrypted key0->keyB
	A	Begin key update (key0->keyB) -- A generates a session key keySA1 and sends to B, following outgoing communication will be encrypted keySA1->keyB
	B	Acknowledge key update (keyB->key0) -- B confirms reception of the request, following outgoing communication will be encrypted keyB->keySA1
	B	Start password authentication (keyB->keySA1) -- B would like to see password authentication
	A	Acknowledge password authentication (keySA1->keyB) -- A authenticates with password, as requested by B
	B	Begin key update (keyB->keySA1) -- B likes PFS and generates a session key keySB1, following outgoing communication will be encrypted keySB1->keySA1
	A	Acknowledge key update (keySA1->keyB) -- A confirms reception of the request, following outgoing communication will be encrypted keySA1->keySB1
	B	Start tunnel data (keySB1->keySA1) -- B is happy, the tunnel can be started
	-	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 -- A requires encryption to be enabled and sends keyA and nonce initialization, following outgoing communication will be encrypted keyA->key0
	B	Start crypto auth -- B requires encryption to be enabled and sends keyB and nonce initialization, following outgoing communication will be encrypted keyB->key0
	A	Acknowledge crypto auth (keyA->key0) -- A confirms the request, following outgoing communication will be encrypted keyA->keyB
	B	Acknowledge crypto auth (keyB->key0) -- B confirms the request, following outgoing communication will be encrypted keyB->keyA
	A	Begin key update (keyA->keyB) -- A likes PFS and generates a session key keySA1, following outgoing communication will be encrypted keySA1->keyB
	B	Begin key update (keyB->keyA) -- A likes PFS too and generates a session key keySB1, following outgoing communication will be encrypted keySB1->keyA
	A	Acknowledge key update (keySA1->keyB) -- A confirms reception of request, following outgoing communication will be encrypted keySA1->keySB1
	B	Acknowledge key update (keySB1->keyA) -- B confirms reception of request, following outgoing communication will be encrypted keySB1->keySA1
	A	Start tunnel data (keySA1->keySB1) -- A is happy
	B	Start tunnel data (keySB1->keySA1) -- B is happy too, start the tunnel
	-	VPN traffic (keySA1<->keySB1)
	A	Begin key update (keySA1->keySB1) -- A likes strong PFS and generates a new session key, following outgoing communication will be encrypted keySA2->keySB1
	A	VPN traffic (keySA2->keySB1)
	B	VPN traffic (keySB1->keySA1)
	B	Acknowledge key update (keySB1->keySA1) -- B confirms reception of request, following outgoing communication will be encrypted keySB1->keySA2
	-	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 -- A requires encryption to be enabled and sends keyA and nonce initialization, following outgoing communication will be encrypted keyA->key0
	B	Start crypto auth -- B requires encryption to be enabled and sends keyB and nonce initialization, following outgoing communication will be encrypted keyB->key0
	A	Acknowledge crypto auth (keyA->key0) -- A confirms the request, following outgoing communication will be encrypted keyA->keyB
	B	Acknowledge crypto auth (keyB->key0) -- B confirms the request, following outgoing communication will be encrypted keyB->keyA
	A	Disable encryption (keyA->keyB) -- A does not actually want encryption, it was just for authentication, following outgoing data will be unencrypted
	B	Acknowledge disable encryption (keyB->keyA) -- B is okay with that, following outgoing data will be unencrypted
	A	Start tunnel data -- A is happy
	B	Start tunnel data -- B is happy too, start the tunnel
	-	VPN traffic