2000-09-17 19:57:39 +00:00
|
|
|
This is the security documentation for tinc, a Virtual Private Network daemon.
|
|
|
|
|
|
|
|
Copyright 2000 Guus Sliepen <guus@sliepen.warande.net>,
|
|
|
|
2000 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.
|
|
|
|
|
2000-09-25 20:08:50 +00:00
|
|
|
$Id: SECURITY,v 1.1.2.3 2000/09/25 20:08:50 guus Exp $
|
2000-09-17 19:57:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
1. Authentication
|
|
|
|
------------------
|
|
|
|
|
2000-09-17 20:11:59 +00:00
|
|
|
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)
|
|
|
|
---------------------------------------
|
|
|
|
Any negotations about the meta protocol
|
|
|
|
encryption go here(u).
|
|
|
|
---------------------------------------
|
|
|
|
send_ack(u)
|
|
|
|
send_ack(u)
|
|
|
|
---------------------------------------
|
|
|
|
Other requests(E)...
|
|
|
|
|
|
|
|
(u) Unencrypted,
|
|
|
|
(R) RSA,
|
|
|
|
(H) SHA1,
|
|
|
|
(E) Encrypted with symmetric cipher.
|
|
|
|
|
2000-09-25 20:08:50 +00:00
|
|
|
See section 4 for a detailed example version of the authentication.
|
|
|
|
|
2000-09-17 19:57:39 +00:00
|
|
|
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.
|
|
|
|
|
2000-09-25 20:08:50 +00:00
|
|
|
Every tinc host has its own public/private key pair. Suppose there are two
|
2000-09-17 19:57:39 +00:00
|
|
|
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.
|
|
|
|
|
|
|
|
Instead of doing RSA encryption again, tinc will use a part of the random
|
|
|
|
string that was exchanged during the authentication phase as the key for the
|
|
|
|
symmetric cipher. Some symmetric ciphers require a random initialisation vector
|
|
|
|
for improved security. This vector can be taken from the random string as well.
|
|
|
|
|
|
|
|
Is this secure? I (Guus Sliepen) think at this moment that it is:
|
|
|
|
|
|
|
|
- Since the random string cannot be decrypted by anyone eavesdropping or
|
|
|
|
playing man-in-the-middle, the symmetric key cannot be known by sniffing.
|
|
|
|
- The unencrypted returned hash value is supposed to be cryptographically
|
|
|
|
secure. Furthermore, it can only at most give a way 160 bits of information
|
|
|
|
from the complete random string which is longer than the key for the
|
|
|
|
symmetric cipher, so very few bits will actualy contain information about
|
|
|
|
the symmetric cipher key alone, if any.
|
|
|
|
- If the RSA encryption is cracked, the rest of the communications can be
|
|
|
|
decrypted anyway.
|
|
|
|
- If the symmetric cipher encryption is cracked without using the information
|
|
|
|
from the encrypted random strings or the hash values, this still won't give
|
|
|
|
the full plaintext for the random string, so it won't facilitate a known-
|
|
|
|
plaintext attack on the RSA encryption.
|
|
|
|
- RSA and symmetric ciphers are fundamentally different. It is very unlikely
|
|
|
|
that the overlap of both will create any interference that will facilitate
|
|
|
|
an easier-than-brute-force attack.
|
|
|
|
|
|
|
|
Other options for key exchange could be:
|
|
|
|
|
|
|
|
* A second exchange of RSA encrypted random strings.
|
|
|
|
This is equal to the former scheme just without knowing the hash value of
|
2000-09-25 20:08:50 +00:00
|
|
|
the unecrypted random string. Information theory tells that two seperate
|
|
|
|
RSA messages are as secure as one if the total amount of bits sent is the
|
|
|
|
same, so enlarging the challenge will make one exchange just as secure as
|
|
|
|
two seperate exchanges.
|
2000-09-17 19:57:39 +00:00
|
|
|
|
|
|
|
* Diffie-Hellman with RSA signing.
|
2000-09-25 20:08:50 +00:00
|
|
|
This should be very secure, but there are a lot of pitfalls with using both
|
2000-09-17 19:57:39 +00:00
|
|
|
encryption with public keys and private keys together with the same keypair.
|
|
|
|
|
|
|
|
* Diffie-Hellman with passphrases.
|
|
|
|
This is what tinc <= 1.0pre2 used to do. Passphrases are secret, exchanging
|
|
|
|
them must be done with great care, nobody may eavesdrop. Exchanging public
|
|
|
|
keys on the other hand is much safer, everybody may eavesdrop, just as long
|
|
|
|
as you are sure that the public key itself belongs to the right owner.
|
2000-09-17 20:11:59 +00:00
|
|
|
|
|
|
|
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.
|
2000-09-25 20:08:50 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
and ACK are in reality replaced by the numbers 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
|
|
|
|
\________/\__/
|
|
|
|
| +----> 64 bits initial vector and
|
|
|
|
+-----------> 448 bits symmetric cipher key for meta
|
|
|
|
data sent to the server
|
|
|
|
\______________________________/
|
|
|
|
+-> 2048 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
|
|
|
|
\________/\__/
|
|
|
|
| +----> 64 bits initial vector and
|
|
|
|
+-----------> 448 bits symmetric cipher key for meta
|
|
|
|
data sent to the client
|
|
|
|
\______________________________/
|
|
|
|
+-> 2048 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 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 CHALLENGE. Ofcourse, this key is taken from the decrypted
|
|
|
|
version of that CHALLENGE, 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.
|