Introducing TLS

"Sam Berlin" <[email protected]>
Newsgroups gmane.network.gnutella.devel
Message-ID <[email protected]>
(My apologies if this got sent out twice.  Apparently the first message
did not get sent properly.)

Introducing TLS

We are in the process of incorporating TLS into LimeWire.  After some
discussions with gtk-gnutella (who already had incorporated some use of
TLS),
we have come up with the following plan for using TLS and spreading
knowledge
of TLS hosts throughout the network.

The most fundamental thought behind any changes was that everything must
be
backwards compatable, so existing hosts can continue to parse TLS-aware
messages
and use TLS-aware hosts without problems.  This means that there is no
*requirement* for TLS.  Instead, hosts are advertised as 'tls-capable',
meaning
they will accept incoming TLS connections, but will also accept
plaintext
connections.

The obvious way of doing this is to introduce a second list 'TLS
capable' hosts
whereever a list of ip:port pairs are sent.  That approach leads to a
lot of
duplication, though, especially because hosts are capable of both
plaintext and
TLS connections, and it may be that some newer TLS-aware clients out
there may
just not want to make a TLS connection, so the plaintext information
should be
sent for all hosts as well.

The scheme we settled upon was to send a TLS-capable index list wherever
a list
of ip:ports was sent.  So, if a list of ip:ports was sent in a GGEP
field 'IPP',
then in the GGEP field 'IPP_TLS', there's a new byte[], the bits of
which
indicate which items in the IPP list are TLS-capable.  For example,
given the
host list:

 
....0..........1..........2..........3..........4..........5...........6\
......
  1.2.3.4:5, 2.3.4.5:6, 3.4.5.6:7, 4.5.6.7:8, 5.6.7.8:9, 6.7.8.9:10,
7.8.9.10:11


the byte 0x4A (which in bits is: 01001010) would mean that hosts 1, 4,
and 6
are capable of receiving incoming TLS connections.  When the list is
transferred
in ASCII format (for example, in X-Alts), the tls capable hosts are
indicated
using a hexademical reprensetation of the byte.  In this case, tls=4A. 
More
specific details about X-Alt and other cases are listed below.

All hosts should listen to both plaintext and TLS connections on the
same port.
This is possible by accepting incoming plaintext connections, attempting
to
dispatch them according to the expected word, and if no matching word
arrives,
attempting to convert the data to a TLS connection.  Alternately, one
can assume
all incoming connections are TLS capable, and fallback to a plaintext
connection
if the incoming connection didn't send a correct TLS start sequence. 
Listening
on a single port for both TLS and plaintexts solves many problems of
passing TLS
knowledge to both old tls-unaware, new tls-aware and new
tls-aware-but-uncapable
hosts.

When sending TLS information, a host should always propagate information
of
other's support, but only include their own support if they are capable
of
accepting TLS.

All hosts advertising support for TLS *must* accept at a very minimum
the cipher
suite 'TLS_DH_anon_WITH_AES_128_CBC_SHA'.  The server also should not
require,
nor want client authentication.  Additional cipher suites may be
supported, and
will be advertised and decided upon during the TLS handshake.

The changes to existing Gnutella features are widespread, but minimal. 
They are
as follows.

Alternate Locations Headers:
  The X-Alt header is changed so that "tls=##" is written prior to any of
the
  locations are listed.  '##' is the hexademical representation of the
byte[]
  that describes which of the following alternate locations can accept
TLS.
  Example:
    X-Alt:
tls=25,1.2.3.4:5,1.2.3.4:6,1.2.3.4:7,1.2.3.4:8,1.2.3.4:9,1.2.3.4:10
  means that the locations 1.2.3.4:7 and 1.2.3.4:10 can accept TLS.

  The X-FAlt header is changed so that when describing push alternate
locations,
  a 'pptls=##' is written prior to any of the push proxies are listed. 
The '##'
  is a hexademical representation of the byte[] that describes which of
the
  following push proxies can accept TLS.  It is important the the pptls
header
  be listed *directly* before the push proxies.  Other features can be
listed
  elsewhere.
  Example:
   X-FAlt: <guid>;pptls=5;1.2.3.4:1;1.2.3.4:2;1.2.3.4:3;1.2.3.4:4
  means that the push proxy 1.2.3.4:2 can accept TLS.
  Example 2:
   X-FAlt:
<guid>;fwt/2;7:1.3.2.5;pptls=A;1.2.3.4:1;1.2.3.4:2;1.2.3.4:3;1.2.3.4:4
  means that the host at 1.3.2.5:7 is capable of fw-fw transfers, version
2, and
  his push proxies at addresses 1.2.3.4:1 and 1.2.3.4:3 can accept TLS.

Query Replies:
  In the per-file response section, a new GGEP element 'ALT_TLS'
describes which
  items in the 'ALT' header can support TLS.
  Example:
   ALT = { 1.2.3.4:5, 1.2.3.4:6, 1.2.3.4:7, 1.2.3.4:8, 1.2.3.4:9,
1.2.3.4:10 }
   ALT_TLS = { 0x25 }
  means that the locations 1.2.3.4:7 and 1.2.3.4:10 can accept TLS.

  In the global GGEP section (not the per-file section), a new GGEP
header 'TLS'
  means that the replier (the host sending this query reply) is can
accept TLS.

  Also in the global GGEP section, a new 'PUSH_TLS' header is used to
describe
  which push proxies (as described by the 'PUSH' header) can accept TLS.

Ping Requests:
  When constructing outgoing ping requests, the bit 0x2 in the header
'SCP' is
  used to indicate the pinger can accept TLS.  This is intended for use
with UDP
  host caches, so that they can cache the information when a host pings
them and
  reply back with TLS information about those hosts when responding to
other
  requests.

Ping Replies:
  The GGEP header 'TLS' is added to mean the ping replier can accept TLS.

  The GGEP header 'IPP_TLS' is used to indicate which hosts in the 'IPP'
header
  can accept TLS.

Push Message:
  A GGEP is added after the standard payload (that is, bytes 26+ are a
GGEP).
  The header 'TLS' is used to indicate the host requesting the push can
accept
  TLS.

Push Proxy HTTP Requests:
  The HTTP push proxy request is updated to include a parameter
"tls=true" to
  inform the proxy that the push it should construct on behalf of the
requestor
  should contain the 'TLS' header.

Capabilities Vendor Message (vendor: '\0\0\0\0', id: 10) :
  The capability 'TLS!' (with version 1) is added indicate that the
connection is
  capable of receiving TLS.  This is used so that information about push
proxy
  TLS-capability may be exchanged even if the active connection is not
through
  TLS.

HeadPing Vendor Message (vendor: 'LIME', id: 23) :
  The version is incremented to '2' to indicate support for receiving
HeadPongs
  in a pure-GGEP format.

HeadPong Vendor Message (vendor: 'LIME', id: 24) :
  The version is incremented to '2' and the payload is converted to a
GGEP-based
  format.  The header 'F' is a byte[] of features, with the bit 0x1
indicating
  that the ponger can accept TLS.  The header 'A' is the list of
alternate
  locations, with the header 'T' being the byte[] to indiciate which
locations
  can accept TLS.  Push alternate locations are placed in the 'P' header,
with
  the binary representation of the push alternate location updated so
that the
  bit 0x80 in the feature byte indicates there is an extra byte
describing which
  push proxies are TLS-capable.  That byte is included directly prior to
any of
  the push proxies are written.

Thanks,
  Sam



[Non-text portions of this message have been removed]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.