151 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
This is the security documentation for tinc, a Virtual Private Network daemon.
 | 
						|
 | 
						|
   Copyright 2000,2001 Guus Sliepen <guus@sliepen.warande.net>,
 | 
						|
             2000,2001 Ivo Timmmermans <itimmermans@bigfoot.com>
 | 
						|
 | 
						|
   Permission is granted to make and distribute verbatim copies of
 | 
						|
   this documentation provided the copyright notice and this
 | 
						|
   permission notice are preserved on all copies.
 | 
						|
 | 
						|
   Permission is granted to copy and distribute modified versions of
 | 
						|
   this documentation under the conditions for verbatim copying,
 | 
						|
   provided that the entire resulting derived work is distributed
 | 
						|
   under the terms of a permission notice identical to this one.
 | 
						|
 | 
						|
   $Id: SECURITY,v 1.1.2.4 2001/01/07 17:08:03 guus Exp $
 | 
						|
 | 
						|
 | 
						|
1.  Authentication
 | 
						|
------------------
 | 
						|
 | 
						|
The authentication protocol (see protocol.c for the up-to-date version) is:
 | 
						|
 | 
						|
   Client               Server
 | 
						|
   send_id(u)
 | 
						|
                        send_challenge(R)
 | 
						|
   send_chal_reply(H)                   
 | 
						|
                        send_id(u)
 | 
						|
   send_challenge(R)
 | 
						|
                        send_chal_reply(H)
 | 
						|
   send_metakey(R)
 | 
						|
                        send_metakey(R)
 | 
						|
   send_ack(u)
 | 
						|
                        send_ack(u)
 | 
						|
   ---------------------------------------
 | 
						|
   Other requests(E)...
 | 
						|
 | 
						|
   (u) Unencrypted,
 | 
						|
   (R) RSA,
 | 
						|
   (H) SHA1,
 | 
						|
   (E) Encrypted with symmetric cipher.
 | 
						|
 | 
						|
See section 4 for a detailed example version of the authentication.
 | 
						|
 | 
						|
Authentication in tinc will be done in a way that is very similar to the way
 | 
						|
the SSH (Secure SHell) authentication protocol works. It is based on public
 | 
						|
key cryptography.
 | 
						|
 | 
						|
Every tinc host has its own public/private key pair. Suppose there are two
 | 
						|
tinc hosts, A and B. If A and B trust each other, they store a copy of
 | 
						|
eachothers public key (in the same way passphrases were stored in versions
 | 
						|
of tinc <= 1.0pre2). They know these public keys beforehand, and the origin
 | 
						|
of the public keys has to be known for sure.
 | 
						|
 | 
						|
To make sure that when a connection is made from A to B that B knows A is
 | 
						|
really who he claims to be, B encrypts a totally random string of bytes with
 | 
						|
A's public key. B also calculates the hash value from the unencrypted random
 | 
						|
string. B then sends the encrypted string to A. A then has to decrypt the
 | 
						|
string, calculate the hash value from that string and send it back to B. Since
 | 
						|
only he who possesses A's private key can decrypt this string, only he can send
 | 
						|
back the correct hash value. So, if B receives the same hash value he
 | 
						|
calculated himself, he knows for sure A is A.
 | 
						|
 | 
						|
Both SSH and tinc use RSA for the public key cryptography. SSH uses MD5 as a
 | 
						|
secure hash algorithm, tinc uses SHA1. The reason for our choice of SHA1 is
 | 
						|
the fact that SHA1 is 160 bits instead of 128 (MD5), which makes brute force
 | 
						|
attacks harder. Also, the OpenSSL documentation recommends SHA1.
 | 
						|
 | 
						|
2.  Key exchange
 | 
						|
----------------
 | 
						|
 | 
						|
The rest of the meta connection in tinc will be encrypted with a symmetric
 | 
						|
block cipher, since RSA is not really suited for this. When a connection is
 | 
						|
made, both sides have to agree on a key for this block cipher. To make sure
 | 
						|
that this key exchange is also done securely, and no man-in-the-middle attack
 | 
						|
is possible, RSA would be the best choice for exchanging keys.
 | 
						|
 | 
						|
3.  Symmetric cipher
 | 
						|
--------------------
 | 
						|
 | 
						|
Since the generalized encryption functions of OpenSSL are used, any symmetric
 | 
						|
cipher that is available in OpenSSL could possibly be used. The default however
 | 
						|
will be Blowfish. Blowfish is widely in use and still has not been cracked
 | 
						|
today (as far as we know). It also is one of the faster ciphers available.
 | 
						|
 | 
						|
4.  Detailed "example" of communication
 | 
						|
---------------------------------------
 | 
						|
 | 
						|
Tinc uses a peer-to-peer protocol, but during the authentication phase we will
 | 
						|
make a distinction between a server (a tinc daemon listening for incoming
 | 
						|
connections) and a client (a tinc daemon that is trying to connect to the tinc
 | 
						|
daemon playing server).
 | 
						|
 | 
						|
The message strings here are kept short for clarity. The real length of the
 | 
						|
exchanged messages is indicated. The capital words ID, CHALLENGE, CHAL_REPLY,
 | 
						|
META_KEY and ACK are in reality replaced by the numbers 0, 1, 2, 3 and 4
 | 
						|
respectively.
 | 
						|
 | 
						|
daemon	message
 | 
						|
--------------------------------------------------------------------------
 | 
						|
server	<listening for connection>
 | 
						|
client  <tries to connect>
 | 
						|
server  <accepts connection>
 | 
						|
client	ID client 8 0
 | 
						|
              |   | +-> options
 | 
						|
              |   +---> version
 | 
						|
              +-------> name of tinc daemon
 | 
						|
server  CHALLENGE 57fb4b2ccd70d6bb35a64c142f47e61d
 | 
						|
                  \______________________________/
 | 
						|
                                 +-> KEYLENGTH bits totally random string, encrypted
 | 
						|
                                     with client's public RSA key
 | 
						|
client	CHAL_REPLY 191e23
 | 
						|
                      +-> 160 bits SHA1 value of the complete decrypted
 | 
						|
                          CHALLENGE sent by the server
 | 
						|
server	ID server 8 0
 | 
						|
              |   | +-> options
 | 
						|
              |   +---> version
 | 
						|
              +-------> name of tinc daemon
 | 
						|
client	CHALLENGE da02add1817c1920989ba6ae2a49cecb
 | 
						|
                  \______________________________/
 | 
						|
                                 +-> KEYLENGTH bits totally random string, encrypted
 | 
						|
                                     with server's public RSA key
 | 
						|
server	CHAL_REPLY 2bdeed
 | 
						|
                      +-> 160 bits SHA1 value of the complete decrypted
 | 
						|
                          CHALLENGE sent by the client
 | 
						|
client  META_KEY 5f0823a93e35b69e7086ec7866ce582b
 | 
						|
                  \______________________________/
 | 
						|
                                 +-> KEYLENGTH bits totally random string, encrypted
 | 
						|
                                     with server's public RSA key
 | 
						|
server  META_KEY 6ab9c1640388f8f045d1a07f8a672630
 | 
						|
                  \______________________________/
 | 
						|
                                 +-> KEYLENGTH bits totally random string, encrypted
 | 
						|
                                     with client's public RSA key
 | 
						|
client	ACK
 | 
						|
server	ACK
 | 
						|
--------------------------------------------------------------------------
 | 
						|
 | 
						|
When the server receives the ACK from the client, it should prepare itself
 | 
						|
for the fact that any subsequent data will be encrypted with the key the server
 | 
						|
sent itself in the META_KEY. Ofcourse, this key is taken from the decrypted
 | 
						|
version of that META_KEY, so that we will know for sure only the real client
 | 
						|
can send us messages. The same goes for the client when it receives an ACK.
 | 
						|
 | 
						|
5.  Encryption of VPN packets
 | 
						|
-----------------------------
 | 
						|
 | 
						|
The VPN packets are also encrypted, but with a different key than the one used
 | 
						|
for the meta connection. The reason is that VPN packets can also come from
 | 
						|
other clients which do not have a meta connection with server. Each tinc daemon
 | 
						|
propagates (on request) a separate key for packets that it receives. This key
 | 
						|
is a random string, generated on the fly. Since it is exchanged using the meta
 | 
						|
connection, this key itself will be encrypted.
 |