
Tunnel Vision Technical Information
===================================

This file is here to give you some more detailed information about Tunnel
Vision, its use of encryption, its packet formats, and other things that
seemed too complicated for the README file aimed at normal people.

If you're an encryption nut, hacker, or smart person, or you're looking to
learn more about Tunnel Vision's internal workings, read on!


Encryption in TV
================

Tunnel Vision uses RSA and Blowfish encryption to authenticate remote
servers, and to protect your data from prying eyes as it crosses the
internet.

We didn't implement the encryption algorithms ourselves -- instead, we left
that to the experts.  We use the free SSLeay library by Eric Young.  The
SSLeay library has been around for a long time and has been reviewed and
used by hundreds of people, so it probably doesn't have any major security
flaws.  We could never honestly promise you such a thing in an early release
of TV if we wrote the encryption routines ourselves.  Even large software
companies can't seem to do it when they produce high-budget programs
like IE.

But Tunnel Vision is responsible for actually using these algorithms.  If
you're very concerned about security, you should go over the following
information, or have someone do it for you.  Furthermore, you should look at
the code itself and make sure we didn't do anything stupid.  The tiniest
error could render even the strongest encryption algorithm weak or useless.

Or, you could just trust us.  That's what most people will do.


Play-by-Play
============

The following is a step-by-step description of how TV sets up a connection.

1) Generating a key

   The first thing TV does when it runs is generate a 1024-bit RSA
   public/private key pair using the strongest random number source we know
   of -- the linux /dev/random device.  It stores that in /etc/tunnelv.conf
   for use in future runs of Tunnel Vision.
   
2) Making a connection

   The tunnelv program either waits on a particular TCP port, or makes a
   connection to a known TCP port on another server.  The first thing it
   does is exchange RSA public keys with the other end.  Until starting
   Blowfish, all the following communication is encrypted using RSA.
   
3) Increasing connection randomness

   To make the connection somewhat more confusing to observers, we generate
   around 70 bytes more random data and send it (RSA encrypted) across the
   link.  Since RSA encrypts really large blocks, this isn't as useful here
   as it is for Blowfish, below.
   
4) Switching to Blowfish

   The client end of the TV link now generates 128 bits of random data and
   sets it up as a Blowfish key.  This is known as the "one-time session
   key" -- each time TV connects, it uses a different session key.  It sends
   that (RSA encrypted) across to the server.  From now on, _all_
   communications will be done using Blowfish.
   
5) More connection randomness

   We are using an implementation of Blowfish in which the contents of each
   encrypted block depends on all the previous blocks.  However, for the
   first block, the state is always zero.  Worse, the next command we send
   may start with the long and well-known word "password".  In theory,
   it may be possible to guess the Blowfish key using a "known plaintext"
   attack on the first few Blowfish-encrypted bytes.
   
   To avoid this, we send another 70 (or so -- the length is random too)
   bytes of completely random data.  Only the first two bytes of this is
   known, and that should be far too little to analyze the encryption stream
   effectively.
   
   Now we can safely send the "normal" data for our connection, since the
   encryption of subsequent blocks all depends on the value of the
   randomness, which could not have been predicted by an outside observer.

6) Optional Password Authentication

   Now that we are using a secure and fast Blowfish-encrypted data stream,
   the server considers asking for a password.  This is only necessary if
   the RSA public key of the client has not been authenticated before.  Once
   the client sends the password once, it's enough -- it is authenticated
   immediately and this step is skipped automatically.
   
   In fact, you can even remove the "Magic Password" line from
   /etc/tunnelv.conf when this is done.  That way, the client can't ever be
   tricked into sending its authentication password to an attacker.
   
7) Network configuration -- IHAVE

   The client and server now try to figure out which subnets are "local" to
   them.  They do this based on the contents of the network interface list
   and the routing table, and normally they make pretty good guesses.  Both
   ends send an IHAVE line listing all their local subnets.
   
   When a TV client or server receives an IHAVE line, it looks at each
   remote subnet in turn, to decide whether it wants to send that subnet
   through the tunnel.  If that subnet is local to the TV system, it doesn't
   make sense to tunnel it -- you might end up with routing loops.  For
   example, both ends of any tunnel will have the 127.0.0.1 address, but
   there's no point in sending it over the tunnel.
   
   You can manually set routes too.  Put them on the "Local Nets" line in
   /etc/tunnelv.conf.  For example:
	[Tunnel Vision]
	Local Nets = 192.168.42.0/255.255.255.0 192.168.43.0/255.255.255.0
 
8) Packet exchange

   The client and server now bring up their ethertap network interfaces (see
   below) and shift out of command mode into packet mode.  There is
   currently no way to escape back to command mode (eg. to update the
   routing table) but this may change in the future.


The Ethertap
============

Ethertap is a special network interface available in Linux 2.1.x that allows
you to directly send and receive ethernet-like frames in a stream and have
them processed by the kernel.  You should see the kernel documentation for
more information, but to summarize, Tunnel Vision uses ethertap like this:

	server tap0 -- /dev/tap0 -- (Tunnel) -- /dev/tap0 -- client tap0
	
Where /dev/tap0 is a device file that accepts and receives ethernet packets,
and tap0 is a normal network device (ifconfig, route, etc) that appears to
be sending and receiving the packets.

Tunnel Vision needs the ethertap device in order to function, and it's only
available in the 2.1.x kernels.  If you have any better ideas, let us know.


The Packet Protocol
===================

The packet protocol we chose is kind of a compromise between flexibility and
performance.  Originally, we were including the entire ethernet frame
(hardware addresses and all) in the packets, but this turned out to be
really ugly -- it added 16 extra bytes of data to every single packet that
got forwarded.  If you consider that telnet sessions often have just one
byte of actual data (say, a keypress) in a packet, you can see that this
would almost double the lag time.

So we dumped the ethernet header.  Unfortunately, that means there is no
hardware protocol information at all in each packet.  So, only TCP/IP can be
forwarded.  Perhaps someday we'll fix this up, if there's a demand.

Anyway, the packet format is really simple now:
	[16-bit packet length - network byte order]
	[IP header]
	[contents of IP packet]


Q & A
=====

Here are some answers to questions we expect you to have.

1) Can't you make it work without a 2.1 kernel?  Does it really need Linux?

   We don't know of a way to improve the current situation.  We could
   _receive_ packets in a way similar to tap0 by using a RAW mode socket in
   Linux, but we don't know of any way to inject new packets into the data
   stream as cleanly as tap0 does.  The ethertap device also makes the
   user interface cleaner, since it uses the well-known ifconfig and route
   commands.

   You may be able to make this work on a non-Linux system, but it would be
   a lot of work, and we don't have any such systems.  Feel free to
   volunteer.


2) Do you have to use the patented RSA algorithm?  Why not DH or DSA?

   Nope, RSA isn't required at all, and the protocol is extensible to handle
   any kind of encryption.  Feel free to write the wrapper code for your
   favourite encryption algorithm and send it to us.  Look in
   tunnelv/wvcrypto.cc for examples.


3) Why did you use a TCP stream?  Doesn't that horribly mess up my latency?

   You're right, TCP is a bad choice from a performance point of view.
   Maybe we will write a UDP-able version of TV someday.  Meanwhile, here
   are a few reasons for using TCP:
   
    - It's easier to use with firewalls.  Most firewalls pass TCP
      connections through without problems, while many have trouble with
      UDP.

    - It was much easier to write.  TCP handles all the reliability issues
      by itself, so we can just send data back and forth and expect it to
      get there.  This is most important in command mode, of course.
      
    - It's easier to test.  You can telnet to a TV server and type commands
      at it.
      
    - Better encryption.  Since TCP guarantees that all data will arrive,
      and in the right order, we can use the "streaming" version of Blowfish
      so that each packet's encryption result can depend on the last.  Since
      most TCP/IP packets start with very similar data, a set of
      non-streaming TCP/IP packets could, perhaps, be susceptible to a
      "known plaintext" attack.


4) Why not just use IPsec?

   Because it's not completely standardized yet, and because we are unsure
   of the quality of the Linux implementation.  We needed VPN software
   for the immediate future, so we wrote it ourselves.
   
   In the long run, IPsec is a much better idea and will probably supercede
   any other VPN software, including TV.  Good!
   
   Tunnel Vision is really an intermediate solution.  What it does, it does
   today, and it does it reliably.
   

5) What about PPTP (Microsoft's Point to Point Tunneling Protocol)?

   Recently, some very (very) nasty security bugs have been found in
   Microsoft's PPTP implementation.  The bugs may actually be in the
   protocol definition itself, not just the implementation.
   
   Also, PPTP isn't standardized yet either.  Trying to keep up with
   changing standards is never fun.

   People are working on PPTP for Linux, though.  Take a look around the
   internet if you're interested.

